db4o Tutorial 中文翻译(九)

本文介绍了使用db4o进行复杂对象存储与检索的过程,包括设置更新深度、收集传感器读数、检索所有快照及按顺序检索快照等操作。

7. 深层探险


我们已经看到db4o是如何处理对象关系的了,但是我们使用的例子比起现实世界来都过于简单。特别是,我们没有看到db4o在循环结构中如何存储。现在我们来仿真这样的一个结构:隐性的将之前的history list替换为sensorReadout类的对象。
ContractedBlock.gifExpandedBlockStart.gifSensor Readout
None.gifusing System;
None.gif
namespace Db4objects.Db4o.Tutorial.F1.Chapter5
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{   
InBlock.gif    
public abstract class SensorReadout
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        DateTime _time;
InBlock.gif        Car _car;
InBlock.gif        
string _description;
InBlock.gif        SensorReadout _next;
InBlock.gif        
InBlock.gif        
protected SensorReadout(DateTime time, Car car, string description)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            _time 
= time;
InBlock.gif            _car 
= car;
InBlock.gif            _description 
= description;
InBlock.gif            _next 
= null;            
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public Car Car
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return _car;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public DateTime Time
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return _time;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public SensorReadout Next
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return _next;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public void Append(SensorReadout sensorReadout)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (_next == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                _next 
= sensorReadout;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                _next.Append(sensorReadout);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public int CountElements()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return (_next == null ? 1 : _next.CountElements() + 1);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
override public string ToString()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return string.Format("{0} : {1} : {2}", _car, _time, _description);
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

car只和 'head' sensor readout 有关系:
ContractedBlock.gifExpandedBlockStart.gifnew car
None.gifusing System;
None.gif
namespace Db4objects.Db4o.Tutorial.F1.Chapter5
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
public class Car
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
string _model;
InBlock.gif        Pilot _pilot;
InBlock.gif        SensorReadout _history;
InBlock.gif        
InBlock.gif        
public Car(string model)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            _model 
= model;
InBlock.gif            _pilot 
= null;
InBlock.gif            _history 
= null;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public Pilot Pilot
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return _pilot;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                _pilot 
= value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public string Model
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return _model;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public SensorReadout GetHistory()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return _history;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public void Snapshot()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{        
InBlock.gif            AppendToHistory(
new TemperatureSensorReadout(
InBlock.gif                DateTime.Now, 
this"oil", PollOilTemperature()));
InBlock.gif            AppendToHistory(
new TemperatureSensorReadout(
InBlock.gif                DateTime.Now, 
this"water", PollWaterTemperature()));
InBlock.gif            AppendToHistory(
new PressureSensorReadout(
InBlock.gif                DateTime.Now, 
this"oil", PollOilPressure()));
ExpandedSubBlockEnd.gif        }

InBlock.gif        
protected double PollOilTemperature()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return 0.1*CountHistoryElements();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
protected double PollWaterTemperature()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return 0.2*CountHistoryElements();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
protected double PollOilPressure()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return 0.3*CountHistoryElements();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
override public string ToString()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return string.Format("{0}[{1}]/{2}", _model, _pilot, CountHistoryElements());
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
private int CountHistoryElements()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return (_history == null ? 0 : _history.CountElements());
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
private void AppendToHistory(SensorReadout readout)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (_history == null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                _history 
= readout;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                _history.Append(readout);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif

7.1. 存储和更新


这里没有不同:
None.gif// storeCar
None.gif
Pilot pilot = new Pilot("Rubens Barrichello"99);
None.gifCar car 
= new Car("BMW");
None.gifcar.Pilot 
= pilot;
None.gifdb.Set(car);
现在建立一个 sensor readout 链.。首先设置更新深度:
None.gif// setCascadeOnUpdate
None.gif
Db4oFactory.Configure().ObjectClass(typeof(Car)).CascadeOnUpdate(true);



收集一些sensor readouts.
None.gif// takeManySnapshots
None.gif
IObjectSet result = db.Get(typeof(Car));
None.gifCar car 
= (Car)result.Next();
None.gif
for (int i=0; i<5; i++)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    car.Snapshot();
ExpandedBlockEnd.gif}

None.gifdb.Set(car);

7.2. 检索


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

首先,来验证是否有了很多的snapshots.:
None.gif// retrieveAllSnapshots
None.gif
IObjectSet result = db.Get(typeof(SensorReadout));
None.gif
while (result.HasNext())
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    Console.WriteLine(result.Next());
ExpandedBlockEnd.gif}

这些readouts 都是属于一个相联系的链, 所有我们需要通过对结构的检索来访问他们:

None.gif// retrieveSnapshotsSequentially
None.gif
IObjectSet result = db.Get(typeof(Car));
None.gifCar car 
= (Car)result.Next();
None.gifSensorReadout readout 
= car.GetHistory();
None.gif
while (readout != null)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    Console.WriteLine(readout);
InBlock.gif    readout 
= readout.Next;
ExpandedBlockEnd.gif}

看看,发生了什么?

7.2.1. 激活深度


这只是更新深度的另外一方面问题。.

当你从数据库提取数据后,db4o并不会跟踪引用。所以,获取“完整”的对象需要你自己去检索。如果不是这样的话,当你有很多个对象引用的时候,只想执行一个简单的检索的时候,db4o就要把整个数据库翻一个底朝天,然后把这么多数据一下子读入内存。.

在多数情况下,这样做是不好的。所以db4o提供了一个机制,可以完全按照客户的需要来检索对象。这个机制叫做激活深度,和更新深度非常象。

默认的激活深度为5,所以,上面的代码得到了5个引用。

激活深度是可以设置的。这就可以实现我们的要求--获取所有的sensor readout。

None.gif// retrieveSnapshotsSequentiallyImproved
None.gif
IObjectSet result = db.Get(typeof(Car));
None.gifCar car 
= (Car)result.Next();
None.gifSensorReadout readout 
= car.GetHistory();
None.gif
while (readout != null)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    db.Activate(readout, 
1);
InBlock.gif    Console.WriteLine(readout);
InBlock.gif    readout 
= readout.Next;
ExpandedBlockEnd.gif}

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

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

None.gif// setActivationDepth
None.gif
Db4oFactory.Configure().ObjectClass(typeof(TemperatureSensorReadout))
None.gif    .CascadeOnActivate(
true);


None.gif// retrieveSnapshotsSequentially
None.gif
IObjectSet result = db.Get(typeof(Car));
None.gifCar car 
= (Car)result.Next();
None.gifSensorReadout readout 
= car.GetHistory();
None.gif
while (readout != null)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    Console.WriteLine(readout);
InBlock.gif    readout 
= readout.Next;
ExpandedBlockEnd.gif}




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

不要忘记清空数据库。

None.gif// deleteAll
None.gif
IObjectSet result = db.Get(typeof(Object));
None.gif
foreach (object item in result)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    db.Delete(item);
ExpandedBlockEnd.gif}

7.3. 总结

 

现在,我们已经可以处理复杂的类了。但是,这些都在这样的一个假设下:所有的操作都是对的,当你需要会滚操作的时候该怎么办呢?在下一章节将讲到这个问题。



7.4. 全部代码:

 

None.gif锘縰sing System;
None.gif
using System.IO;
None.gif
using Db4objects.Db4o;
None.gif
namespace Db4objects.Db4o.Tutorial.F1.Chapter5
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    
public class DeepExample : Util
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            File.Delete(Util.YapFileName);
InBlock.gif            IObjectContainer db 
= Db4oFactory.OpenFile(Util.YapFileName);
InBlock.gif            
try
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                StoreCar(db);
InBlock.gif                db.Close();
InBlock.gif                SetCascadeOnUpdate();
InBlock.gif                db 
= Db4oFactory.OpenFile(Util.YapFileName);
InBlock.gif                TakeManySnapshots(db);
InBlock.gif                db.Close();
InBlock.gif                db 
= Db4oFactory.OpenFile(Util.YapFileName);
InBlock.gif                RetrieveAllSnapshots(db);
InBlock.gif                db.Close();
InBlock.gif                db 
= Db4oFactory.OpenFile(Util.YapFileName);
InBlock.gif                RetrieveSnapshotsSequentially(db);
InBlock.gif                RetrieveSnapshotsSequentiallyImproved(db);
InBlock.gif                db.Close();
InBlock.gif                SetActivationDepth();
InBlock.gif                db 
= Db4oFactory.OpenFile(Util.YapFileName);
InBlock.gif                RetrieveSnapshotsSequentially(db);
ExpandedSubBlockEnd.gif            }

InBlock.gif            
finally
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                db.Close();
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void StoreCar(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Pilot pilot 
= new Pilot("Rubens Barrichello"99);
InBlock.gif            Car car 
= new Car("BMW");
InBlock.gif            car.Pilot 
= pilot;
InBlock.gif            db.Set(car);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void SetCascadeOnUpdate()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Db4oFactory.Configure().ObjectClass(
typeof(Car)).CascadeOnUpdate(true);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void TakeManySnapshots(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(typeof(Car));
InBlock.gif            Car car 
= (Car)result.Next();
InBlock.gif            
for (int i=0; i<5; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                car.Snapshot();
ExpandedSubBlockEnd.gif            }

InBlock.gif            db.Set(car);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void RetrieveAllSnapshots(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(typeof(SensorReadout));
InBlock.gif            
while (result.HasNext())
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(result.Next());
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void RetrieveSnapshotsSequentially(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(typeof(Car));
InBlock.gif            Car car 
= (Car)result.Next();
InBlock.gif            SensorReadout readout 
= car.GetHistory();
InBlock.gif            
while (readout != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Console.WriteLine(readout);
InBlock.gif                readout 
= readout.Next;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void RetrieveSnapshotsSequentiallyImproved(IObjectContainer db)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            IObjectSet result 
= db.Get(typeof(Car));
InBlock.gif            Car car 
= (Car)result.Next();
InBlock.gif            SensorReadout readout 
= car.GetHistory();
InBlock.gif            
while (readout != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                db.Activate(readout, 
1);
InBlock.gif                Console.WriteLine(readout);
InBlock.gif                readout 
= readout.Next;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public static void SetActivationDepth()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Db4oFactory.Configure().ObjectClass(
typeof(TemperatureSensorReadout))
InBlock.gif                .CascadeOnActivate(
true);
ExpandedSubBlockEnd.gif        }

InBlock.gif        
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif


转载于:https://www.cnblogs.com/xxpyeippx/archive/2007/05/06/737067.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值