User:Alexyakunin/DataObjects.Net
File:DataObjects.Net.png | |
Developer(s) | X-tensive.com |
---|---|
Stable release | 4.0 beta
/ May 2, 2009 |
Written in | C# |
Operating system | Microsoft Windows |
Platform | .NET 3.5 |
Type | Object-relational mapping |
License | GNU v3 or commercial |
Website | http://wiki.dataobjects.net/ |
DataObjects.Net is rapid database application development framework.
It combines comprehensive business logic layer (BLL) development framework, object-relational mapper (ORM) and a set of storage providers enabling the same BLL code to work transparently on any of them. The framework can be used to develop generally any application dealing with persistent data.
Besides other features, DataObjects.Net has built-in embedded database, so it can be used both with and without SQL database.
DataObjects.Net is open source product available under GPL and commercial licenses. The most current version is 4.0.
History
First version of DataObjects.Net was initially designed in 2003 for use in rather special set of cases, mainly – in web-based document management systems. DataObjects.Net 1.0 was developed in ~ 9 months by a 3 - person team. Many its limitations appeared just because authors didn’t though it will be practically useful in much wider set of cases. An example of such limitation is pre-defined type of identifier and version. Nevertheless its initial design was innovative for that period - in comparison to other persistence frameworks on the market. Finally the team of developers has made a decision to completely redesign it. This new implementation is known as DataObjects.Net v4.0.
Works on DataObjects.Net v4.0 were started in the beginning of 2007. In September 2008 v4.0 was publicly shown for the first time, although some features (LINQ, schema evolution) were missing in it yet. DataObjects.Net v4.0 final will be released in May 2009.
Features
- Designed for frictionless development of business logic layer (BLL) components providing modularity, reusability, testability for them.
- High level of storage independence. DataObjects.Net allows to transparently migrate between SQL database and index storages, providing:
- Built-in embedded database supporting all the framework features including indexes and LINQ allows to use the product without third-party SQL database at all.
- Built-in in-memory database (IMDB) allowing to use LINQ queries and indexes on the client and simplifying unit testing.
- Relying on PostSharp to implement persistent properties and override persistent object's behavior in AOP fashion.
- Object-relational mapping layer providing support for:
- Automatic creation and upgrade of the database schema on each Domain startup. The upgrade process is fully customizable. Original data is either kept, transformed, or moved to so-called recycle types to be used in custom upgrade handlers.
- Class mapping: framework supports 3 common mapping strategies: class to table, class to concrete table, hierarchy to table. So inheritance is fully supported.
- Interface mapping: DataObjects.Net is capable of mapping interfaces to materializing tables, as well as to ordinary tables, to which Entities implementing the interface are mapped. Materializing tables can be indexed.
- Structures: struct-like objects that Entities may aggregate.
- Arbitrary primary key types, combined primary keys.
- Transparent persistence. No necessity to call neither something like DataContext.Register(newEntity) nor DataContext.Save() -like methods.
- Indexes.
- LINQ.
- Business logic related features:
- "Unit-of-work" pattern implementation and error compensation based on integrated Atomicity framework.
- Support for master-slave and P2P synchronization scenarios between storages running DataObjects.Net out of the box.
- Performance: the framework is designed for it. For example, it intensively uses caching. In particular, query compilation and optimization results, compiled expressions and fetched entities are cached.
Example
Persistent entity:
[HierarchyRoot(typeof(KeyGenerator), "Id")]
public class Message : Entity
{
[Field]
public int Id { get; private set; }
[Field(Length = 1024)]
public string Text { get; set; }
}
Confuguration:
<Xtensive.Storage>
<domains>
<domain name="memory" connectionUrl="memory://localhost/Tests" upgradeMode="Recreate" />
<domain name="mssql" connectionUrl="mssql2005://localhost/Tests" upgradeMode="Recreate" />
<domain name="pgsql" connectionUrl="pgsql://tester:testpwd@localhost:8332/test?Encoding=ASCII" upgradeMode="Recreate" />
</domains>
</Xtensive.Storage>
Building domain:
var configuration = DomainConfiguration.Load("mssql");
configuration.Types.Register(typeof(Message).Assembly);
var domain = Domain.Build(configuration);
Creating entity:
using (domain.OpenSession()) {
using (var transactionScope = Transaction.Open()) {
var message = new Message() {
Text = "Hello World!"
};
transactionScope.Complete();
}
}
Query:
using (domain.OpenSession()) {
using (var transactionScope = Transaction.Open()) {
// This query will be translated to ~ SELECT ... WHERE message.Text LIKE "Hello%"
var helloMessages =
from message in Query<Message>.All
where message.Text.StartsWith("Hello")
select message;
foreach (var message in helloMessages) // Actual execution happens here
Console.WriteLine(message.Text); // Prints "Hello World!"
transactionScope.Complete();
}
}
Architecture
File:DataObjects.Net Framework Architecture.png