Surance Center

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 链.。首先设置更新深度:
// setCascadeOnUpdate
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);

7.2. 检索


现在已经有了一个复杂的结构,我们来检索一下:

首先,来验证是否有了很多的snapshots.:
// retrieveAllSnapshots
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;
}

看看,发生了什么?

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;
}

注意:“消减”引用也会影响对象的行动。在这个例子中,列表的长度是动态计算的,是被激活深度限制的。

不用动态激活深度的话,你可以静态的设置激活深度。可以告诉sensor readout类的对象来自动的瀑布式(递归)的激活。如下面的例子:

// setActivationDepth
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;
}




因为激活深度很复杂,所以你要非常小心。db4o提供了一个很宽范围的设置属性来控制激活深度。这些操作在
Db4objects.Db4o.Config.Configuration 类中,并且与IObjectClass and IObjectField有一定关系。

不要忘记清空数据库。

// deleteAll
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);
        }

        
    }

}



posted @ 2007-05-06 13:17  xxp  阅读(1006)  评论(0编辑  收藏  举报
Surance Center