db4o Tutorial 中文翻译(九)
7. 深层探险
我们已经看到db4o是如何处理对象关系的了,但是我们使用的例子比起现实世界来都过于简单。特别是,我们没有看到db4o在循环结构中如何存储。现在我们来仿真这样的一个结构:隐性的将之前的history list替换为sensorReadout类的对象。
Sensor Readout
car只和 'head' sensor readout 有关系:
new car
7.1. 存储和更新
这里没有不同:
// storeCar
Pilot pilot = new Pilot("Rubens Barrichello", 99);
Car car = new Car("BMW");
car.Pilot = pilot;
db.Set(car);
现在建立一个 sensor readout 链.。首先设置更新深度:Pilot pilot = new Pilot("Rubens Barrichello", 99);
Car car = new Car("BMW");
car.Pilot = pilot;
db.Set(car);
// setCascadeOnUpdate
Db4oFactory.Configure().ObjectClass(typeof(Car)).CascadeOnUpdate(true);
Db4oFactory.Configure().ObjectClass(typeof(Car)).CascadeOnUpdate(true);
收集一些sensor readouts.
// takeManySnapshots
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
for (int i=0; i<5; i++)
{
car.Snapshot();
}
db.Set(car);
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
for (int i=0; i<5; i++)
{
car.Snapshot();
}
db.Set(car);
7.2. 检索
现在已经有了一个复杂的结构,我们来检索一下:
首先,来验证是否有了很多的snapshots.:
// retrieveAllSnapshots
IObjectSet result = db.Get(typeof(SensorReadout));
while (result.HasNext())
{
Console.WriteLine(result.Next());
}
IObjectSet result = db.Get(typeof(SensorReadout));
while (result.HasNext())
{
Console.WriteLine(result.Next());
}
这些readouts 都是属于一个相联系的链, 所有我们需要通过对结构的检索来访问他们:
// retrieveSnapshotsSequentially
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
SensorReadout readout = car.GetHistory();
while (readout != null)
{
Console.WriteLine(readout);
readout = readout.Next;
}
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
SensorReadout readout = car.GetHistory();
while (readout != null)
{
Console.WriteLine(readout);
readout = readout.Next;
}
看看,发生了什么?
7.2.1. 激活深度
这只是更新深度的另外一方面问题。.
当你从数据库提取数据后,db4o并不会跟踪引用。所以,获取“完整”的对象需要你自己去检索。如果不是这样的话,当你有很多个对象引用的时候,只想执行一个简单的检索的时候,db4o就要把整个数据库翻一个底朝天,然后把这么多数据一下子读入内存。.
在多数情况下,这样做是不好的。所以db4o提供了一个机制,可以完全按照客户的需要来检索对象。这个机制叫做激活深度,和更新深度非常象。
默认的激活深度为5,所以,上面的代码得到了5个引用。
激活深度是可以设置的。这就可以实现我们的要求--获取所有的sensor readout。
// retrieveSnapshotsSequentiallyImproved
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
SensorReadout readout = car.GetHistory();
while (readout != null)
{
db.Activate(readout, 1);
Console.WriteLine(readout);
readout = readout.Next;
}
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
SensorReadout readout = car.GetHistory();
while (readout != null)
{
db.Activate(readout, 1);
Console.WriteLine(readout);
readout = readout.Next;
}
注意:“消减”引用也会影响对象的行动。在这个例子中,列表的长度是动态计算的,是被激活深度限制的。
不用动态激活深度的话,你可以静态的设置激活深度。可以告诉sensor readout类的对象来自动的瀑布式(递归)的激活。如下面的例子:
// setActivationDepth
Db4oFactory.Configure().ObjectClass(typeof(TemperatureSensorReadout))
.CascadeOnActivate(true);
Db4oFactory.Configure().ObjectClass(typeof(TemperatureSensorReadout))
.CascadeOnActivate(true);
// retrieveSnapshotsSequentially
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
SensorReadout readout = car.GetHistory();
while (readout != null)
{
Console.WriteLine(readout);
readout = readout.Next;
}
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
SensorReadout readout = car.GetHistory();
while (readout != null)
{
Console.WriteLine(readout);
readout = readout.Next;
}
因为激活深度很复杂,所以你要非常小心。db4o提供了一个很宽范围的设置属性来控制激活深度。这些操作在
Db4objects.Db4o.Config.Configuration 类中,并且与IObjectClass and IObjectField有一定关系。
不要忘记清空数据库。
// deleteAll
IObjectSet result = db.Get(typeof(Object));
foreach (object item in result)
{
db.Delete(item);
}
IObjectSet result = db.Get(typeof(Object));
foreach (object item in result)
{
db.Delete(item);
}
7.3. 总结
现在,我们已经可以处理复杂的类了。但是,这些都在这样的一个假设下:所有的操作都是对的,当你需要会滚操作的时候该怎么办呢?在下一章节将讲到这个问题。
7.4. 全部代码:
锘縰sing System;
using System.IO;
using Db4objects.Db4o;
namespace Db4objects.Db4o.Tutorial.F1.Chapter5
{
public class DeepExample : Util
{
public static void Main(string[] args)
{
File.Delete(Util.YapFileName);
IObjectContainer db = Db4oFactory.OpenFile(Util.YapFileName);
try
{
StoreCar(db);
db.Close();
SetCascadeOnUpdate();
db = Db4oFactory.OpenFile(Util.YapFileName);
TakeManySnapshots(db);
db.Close();
db = Db4oFactory.OpenFile(Util.YapFileName);
RetrieveAllSnapshots(db);
db.Close();
db = Db4oFactory.OpenFile(Util.YapFileName);
RetrieveSnapshotsSequentially(db);
RetrieveSnapshotsSequentiallyImproved(db);
db.Close();
SetActivationDepth();
db = Db4oFactory.OpenFile(Util.YapFileName);
RetrieveSnapshotsSequentially(db);
}
finally
{
db.Close();
}
}
public static void StoreCar(IObjectContainer db)
{
Pilot pilot = new Pilot("Rubens Barrichello", 99);
Car car = new Car("BMW");
car.Pilot = pilot;
db.Set(car);
}
public static void SetCascadeOnUpdate()
{
Db4oFactory.Configure().ObjectClass(typeof(Car)).CascadeOnUpdate(true);
}
public static void TakeManySnapshots(IObjectContainer db)
{
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
for (int i=0; i<5; i++)
{
car.Snapshot();
}
db.Set(car);
}
public static void RetrieveAllSnapshots(IObjectContainer db)
{
IObjectSet result = db.Get(typeof(SensorReadout));
while (result.HasNext())
{
Console.WriteLine(result.Next());
}
}
public static void RetrieveSnapshotsSequentially(IObjectContainer db)
{
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
SensorReadout readout = car.GetHistory();
while (readout != null)
{
Console.WriteLine(readout);
readout = readout.Next;
}
}
public static void RetrieveSnapshotsSequentiallyImproved(IObjectContainer db)
{
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
SensorReadout readout = car.GetHistory();
while (readout != null)
{
db.Activate(readout, 1);
Console.WriteLine(readout);
readout = readout.Next;
}
}
public static void SetActivationDepth()
{
Db4oFactory.Configure().ObjectClass(typeof(TemperatureSensorReadout))
.CascadeOnActivate(true);
}
}
}
using System.IO;
using Db4objects.Db4o;
namespace Db4objects.Db4o.Tutorial.F1.Chapter5
{
public class DeepExample : Util
{
public static void Main(string[] args)
{
File.Delete(Util.YapFileName);
IObjectContainer db = Db4oFactory.OpenFile(Util.YapFileName);
try
{
StoreCar(db);
db.Close();
SetCascadeOnUpdate();
db = Db4oFactory.OpenFile(Util.YapFileName);
TakeManySnapshots(db);
db.Close();
db = Db4oFactory.OpenFile(Util.YapFileName);
RetrieveAllSnapshots(db);
db.Close();
db = Db4oFactory.OpenFile(Util.YapFileName);
RetrieveSnapshotsSequentially(db);
RetrieveSnapshotsSequentiallyImproved(db);
db.Close();
SetActivationDepth();
db = Db4oFactory.OpenFile(Util.YapFileName);
RetrieveSnapshotsSequentially(db);
}
finally
{
db.Close();
}
}
public static void StoreCar(IObjectContainer db)
{
Pilot pilot = new Pilot("Rubens Barrichello", 99);
Car car = new Car("BMW");
car.Pilot = pilot;
db.Set(car);
}
public static void SetCascadeOnUpdate()
{
Db4oFactory.Configure().ObjectClass(typeof(Car)).CascadeOnUpdate(true);
}
public static void TakeManySnapshots(IObjectContainer db)
{
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
for (int i=0; i<5; i++)
{
car.Snapshot();
}
db.Set(car);
}
public static void RetrieveAllSnapshots(IObjectContainer db)
{
IObjectSet result = db.Get(typeof(SensorReadout));
while (result.HasNext())
{
Console.WriteLine(result.Next());
}
}
public static void RetrieveSnapshotsSequentially(IObjectContainer db)
{
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
SensorReadout readout = car.GetHistory();
while (readout != null)
{
Console.WriteLine(readout);
readout = readout.Next;
}
}
public static void RetrieveSnapshotsSequentiallyImproved(IObjectContainer db)
{
IObjectSet result = db.Get(typeof(Car));
Car car = (Car)result.Next();
SensorReadout readout = car.GetHistory();
while (readout != null)
{
db.Activate(readout, 1);
Console.WriteLine(readout);
readout = readout.Next;
}
}
public static void SetActivationDepth()
{
Db4oFactory.Configure().ObjectClass(typeof(TemperatureSensorReadout))
.CascadeOnActivate(true);
}
}
}
Surance Yin@ Surance Center
转载请注明出处
转载请注明出处