db4o学习笔记(五)、处理结构化对象上

摘要:

  本单元将对db4o如何处理复杂的结构化对象进行详细的介绍,主要内容有:(1)、存储结构化对象;(2)、db4o对于结构化对象的查询操作。另外,有感按照db4o开发文档原文翻译是一件十分费时的工作,为了尽量保证与原文内容上的一致性,会舍去不少东西从而使本笔记的可读性有所降低,为此从下一篇开始采取对原文地概览的方式,然后再增加一个小案例进行实践以此综合运用db4o所提供了各项功能。

正文:  

  是时候对我们的业务模型进行扩展了,看看db4o是如何处理对象之间相互关系的,我们给车手添加一个交通工具。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
namespace com.db4o.f1.chapter2
{
public class Car
{
string _model;
Pilot _pilot;

public Car(string model)
{
_model = model;
_pilot = null;
}

public Pilot Pilot
{
get
{
return _pilot;
}

set
{
_pilot = value;
}
}

public string Model
{
get
{
return _model;
}
}

override public string ToString()
{
return string.Format("{0}[{1}]", _model, _pilot);
}
}
}

  4.1、存储结构化对象

  为了存储含有车手信息的Car对象,只需在顶层对象(Car)调用Set()方法即可,其车手对象也会自动的进行存储。

1
2
3
4
5
[storeFirstCar]
Car car1 = new Car("Ferrari");
Pilot pilot1 = new Pilot("Michael Schumacher", 100);
car1.Pilot = pilot1;
db.Set(car1);

  当然,也存在其它可选的方法,这次在存储Car对象时我们先明确的存储车手信息,再处理Car对象,这和上面的方式没有什么区别。

  

1
2
3
4
5
6
[storeSecondCar]
Pilot pilot2 = new Pilot("Rubens Barrichello", 99);
db.Set(pilot2);
Car car2 = new Car("BMW");
car2.Pilot = pilot2;
db.Set(car2);

  4.2、加载结构化对象

  4.2.1、QBE

  为加载所有的车辆对象,咱依然只需提供一个原型对象。

1
2
3
4
[retrieveAllCarsQBE]
Car proto = new Car(null);
ObjectSet result = db.Get(proto);
ListResult(result);

  我们也可以直接查询所有的车手对象。  

1
2
3
4
[retrieveAllPilotsQBE]
Pilot proto = new Pilot(null, 0);
ObjectSet result = db.Get(proto);
ListResult(result);

  现在将原型对象初始化”Rubens Barrichello”驾驶的车辆。

1
2
3
4
5
6
[retrieveCarByPilotQBE]
Pilot pilotproto = new Pilot("Rubens Barrichello",0);
Car carproto = new Car(null);
carproto.Pilot = pilotproto;
ObjectSet result = db.Get(carproto);
ListResult(result);

  怎样通过车辆信息加载车手对象呢?如果我们知道车辆信息就不必像上面这样,直接存取车手对象即可。

  4.2.2、NQ

  使用NQ查询聚合层次较深的对象也很简单,就像平时处理其它对象一样。来看看通过指定姓名的车手来查询车辆对象的查询。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class RetrieveCarsByPilotNamePredicate : Predicate
{
readonly string _pilotName;

public RetrieveCarsByPilotNamePredicate(string pilotName)
{
_pilotName = pilotName;
}

public bool Match(Car candidate)
{
return candidate.Pilot.Name == _pilotName;
}
}

  通过车手名字查询车辆信息:

1
2
3
4
[retrieveCarsByPilotNameNative]
string pilotName = "Rubens Barrichello";
ObjectSet results = db.Query(new RetrieveCarsByPilotNamePredicate(pilotName));
ListResult(results);

  .NET 2.0语法甚至更简单:

1
2
3
4
5
[retrieveCarsByPilotNameNative] 
string pilotName = "Rubens Barrichello";
List<Car> results = db.Query<Car>(delegate(Car car) {
return car.Pilot.Name == pilotName; });
listResults(results);

  4.2.3、SODA

  为了使用SODA执行同样的查询我们需要向约束条件中添加两个层次的条件。  

1
2
3
4
5
6
7
[retrieveCarByPilotNameQuery]
Query query = db.Query();
query.Constrain(typeof(Car));
query.Descend("_pilot").Descend("_name")
.Constrain("Rubens Barrichello");
ObjectSet result = query.Execute();
ListResult(result);

  也可以通过使用pilot字段的原型对象来达到同样的目的。

1
2
3
4
5
6
7
[retrieveCarByPilotProtoQuery]
Query query = db.Query();
query.Constrain(typeof(Car));
Pilot proto = new Pilot("Rubens Barrichello", 0);
query.Descend("_pilot").Constrain(proto);
ObjectSet result = query.Execute();
ListResult(result);

  再看看采用descend添加约束的方法提供另外的查询示例,从查询的根节点我可以从多条路径添加约束,实际上从子节点向下添加约束与从父节点向下添加约束是一样的。由此可知查询引擎能从任意方向来引用我们的对象到其真实的关系。以下便是查询一个驾驶着拥有法拉利引擎汽车的车手对象的示例:

1
2
3
4
5
6
7
[retrievePilotByCarModelQuery]
Query carQuery = db.Query();
carQuery.Constrain(typeof(Car));
carQuery.Descend("_model").Constrain("Ferrari");
Query pilotQuery = carQuery.Descend("_pilot");
ObjectSet result = pilotQuery.Execute();
ListResult(result);

你可能感兴趣的:(学习笔记)