大多数人接触Db4o的查询,都是从“样本查询”(Query by Example)开始的,这种查询方式简单但不方便,功能和性能也很受局限。以下是引自官方的样本查询示例:
// retrievePilotByName Pilot proto=new Pilot("Michael Schumacher",0); ObjectSet result=db.get(proto); listResult(result);
这种查询要求我们先建立一个样本,然后再交由Db4o根据此样本返回符合条件的数据,其主要的不便之处在于对类默认值的处理及组合条件查询上,同时其执行性能是很差的。
而当Db4o开始支持.Net 3.5之后,我们就有了更为简单且又十分方便而强大的选择了,让我们来一起领略Db4o与.Net 3.5擦出的火花之美吧:
准备工作
首先创建一个命令行应用程序。
书写一个简单的“学生”类:
public class 学生
{
static Random R = new Random();public 学生(int 学号)
{
this.学号 = 学号;
性别 = R.Next(2) == 1;
成绩 = R.Next(101);
}public int 学号 { get; set; }
public bool 性别 { get; set; }
public int 成绩 { get; set; }public override string ToString()
{
return string.Format("学号:{0:0000} 性别:{1} 成绩:{2}", 学号, 性别 ? "男" : "女", 成绩);
}
}
该类就是用于模拟学生的数据,性别和成绩都是在构造时随机生成的。
然后引入Db4o对应.Net 3.5版的dll:
引入命名空间:
using Db4objects.Db4o;
using Db4objects.Db4o.Linq;
在Main函数中编写代码:
var db = Db4oFactory.OpenFile("db.db4o");
for (int i = 0; i < 5000; i++)
{
db.Store(new 学生(i));
}
这段代码用于打开数据库,并存储5000个学生数据到数据库中。
Linq查询
接着编写Linq查询代码,将查询到的集合存入变量l中:
var l = (from 学生 q in db
where !q.性别 && q.成绩 == 100
orderby q.学号 descending
select q).Take(5);
这里我们查询的是所有成绩为100的女生,并将结果按学号降序排列,取最前面的5位。
由此可看出Db4o与Linq结合的非常紧密,我们在使用Linq查询时完全没有任何不适应感,依然是得心应手的感觉。
然后遍历并输出一下结果:
foreach (var f in l)
{
Console.WriteLine(f);
}Console.ReadLine();
查询结果输出:
Lambda表达式查询
其实这个在支持Linq之前就已经获得支持了,或者说支持Lambda表达式这项工作根本不是Db4o开发人员的工作范畴。
我们知道Lambda表达式其实就是一个委托,而Db4o的原生查询(Native Queries)所需的参数就是一个委托,所以也就说在.Net框架引入Lambda表达式的时候,它就已经可以被用在Db4o查询中了。以下是引自官方的原生查询示例:
IList <Pilot> pilots = db.Query <Pilot> (delegate(Pilot pilot) { return pilot.Points == 100; });
你可以很轻松的把它改为Lambda表达式形式:
IList <Pilot> pilots = db.Query <Pilot> (q=>q.Points ==100);
这样就简明许多了吧?
同理,上文的Linq查询也可以改作:
var l = db.Query<学生>(q => !q.性别 && q.成绩 == 100).OrderByDescending(q => q.学号).Take(5);
得到的结果是等同的,而书写上更为方便,推荐使用。
结语
Db4o很好很强大,现在很多一流大企业也都开始使用它了,它在开发效率和数据持久化方式上都带来了质的革新,绝对值得我们学习和使用。
推荐学习资料: 《db4o7.0指南》(译者:hankjin、jeff、lixianfeng、richard.liangyx、cleverpig)