db4o发布7.2,出现.NET 3.5版本,支持LINQ

Db4Object刚刚发布了db4o的7.2beta,除了以前支持如下的平台:.NET 1.1,.NET 2.0,Mono外,现在还支持.NET 3.5了。当然支持.NET 3.5,最主要的时候要来支持LINQ。

关于LINQ,我稍后再讲。现在讲讲7.2中最大的新特性——Transparent Activation(透明激活)。关于7.0版本的其他新特性,可以参看我在InfoQ上的文章《Db4Objects发布Db4o 7.0,支持透明激活》。

要讲到透明激活,我们先来看看之前激活存在的问题。所谓激活,就是在对象从磁盘文件载入到内存过程中,如何加载层级对象的过程。由于对象的层级关系可以无限关联的,所以,db4o之前使用“深度”的概念来明确表明处理对象的时候需要,处理到多少层。但是,这种方式对编程带来很多麻烦,我们在写代码的时候需要随时关心,我们大概要加载多深的对象。这样的估计有时候会比要使用到的多,有时候又会少。多了,造成资源的浪费,少了,不能正确的处理需要处理到的对象。

下面我引用,db4o文档中对这个问题的描述(英文的我就不翻译了):

We can reuse most of the code from the Deep Graphs chapter and get it to work with Transparent Activation.
As a first step we should fill up our database with Car, Pilot and SensorReadout objects, so we have some objects to work with.

// storeCarAndSnapshots
Pilot pilot = new Pilot("Kimi Raikkonen", 110);
Car car = new Car("Ferrari");
car.Pilot = pilot;
for (int i = 0; i < 5; i++)
{
    car.snapshot();
}
db.Store(car);

If we now rerun the code to traverse all cars and their sensor readings, we are again confronted with the same problem that we had before, we end up with some leaves of our object graph being null.  

// retrieveSnapshotsSequentially
IObjectSet result = db.QueryByExample(typeof (Car));
Car car = (Car) result.Next();
SensorReadout readout = car.History;
while (readout != null)
{
    Console.WriteLine(readout);
    readout = readout.Next;
}

为了解决这个问题,db4o在7.0中提出了透明激活的概念,即db4o透明地帮我们处理对象激活的问题。这样可以提供性能,让我们编程更方便。

再次引用db4o文档的代码:

Let's configure db4o to run in Transparent Activation mode and let's try again:

// configureTransparentActivation
Db4oFactory.Configure().Add(new TransparentActivationSupport());

// retrieveSnapshotsSequentially
IObjectSet result = db.QueryByExample(typeof (Car));
Car car = (Car) result.Next();
SensorReadout readout = car.History;
while (readout != null)
{
    Console.WriteLine(readout);
    readout = readout.Next;
}

Wow it worked! Is it really that easy? Principally yes. When db4o is run in Transparent Activation mode there are no surprises with null members that have not yet been read from the database.

好了,透明激活就讲到这里,现在来看看LINQ的支持。Linq在7.0发布之前,在db4o上已经有一个linq to db4o的项目在做前期研究了,现在只是把linq to db4o合并到7.2中一起发布。

linq to db4o提供了一个额外的程序集:Db4objects.Db4o.Linq

要使用linq to db4o,只需要在项目中引用这个程序集。然后打开一个db4o数据库,就可以使用linq语法查询数据了:

Let's prepare some objects in our database to query against:

// storeObjects
db.Store(new Car("Ferrari", (new Pilot("Michael Schumacher", 100))));
db.Store(new Car("BMW", (new Pilot("Rubens Barrichello", 99))));

The simplest LINQ query will look like this:

// retrievePilot
IEnumerable<Pilot> result = from Pilot p in db
                            where p.Name.StartsWith("Michael")
                            select p;
ListResult(result);

You can see that we are using db4o object container as a datasource, the rest of the syntax is generic to all LINQ queries.
Now let's try a bit more complex selection:

// retrievePilotByCar
IEnumerable<Pilot> result = from Car c in db
                            where c.Model.StartsWith("F")
                            && (c.Pilot.Points > 99 && c.Pilot.Points <150)
                            select c.Pilot;
ListResult(result);

另外这里,也有一个linq to db4o的例子:Linq is here!

通过linq来查询db4o确实带来了很多方便,不过现在linq to db4o还没有非常成熟,期待其更加完善成熟。

大家对db4o 7.2有兴趣的,可以到这里下载来试试。