把System.Data.SQLite和ADO.NET(WCF) Data Service双剑合璧

关于System.Data.SQLite,可以参见我之前的介绍博客。不过现在的最新版本1.0.65(2009年7月26日发布),相对之前的版本提供了如下新特性:

  • 包装了sqlite 3.6.16
  • 支持.NET 3.5 SP1
  • 支持Mono
  • 支持VS2008(其实如果你安装了2010的话,也支持的)设计器:数据库管理器,Typed DataSet(类型化数据集)设计器,EDM(实体数据模型)设计器等
  • 最重要的是,几乎完整支持ADO.NET 3.5 Entity Framework(实体框架)。有了这个特性,本文才有存在的意义。

有了System.Data.SQLite这么强大的功能,在某些情况下基本可以替代SQL Server 2005/2008 Express  SQL Server Compact Edition了。

对于ADO.NET Data Service大家应该已经熟知了,现在已经改名为WCF Data Service了。Entity Framework和WCF都是过于底层的技术,在SmartClient或RIA中开发面向数据驱动的应用程序(EF访问数据,WCF直接暴露实体和实体操作的方法),直接使用这两个技术或多或少会遇到不适应的情况,对整个开发效率也有影响。为了解决这样的问题,也为了支持流行的REST访问数据方式,微软研发了Astoria项目,也即ADO.NET(WCF)数据服务。

对于ADO.NET Data Service的使用,可以参见:http://kb.cnblogs.com/page/43963/Astoria (ADO.NET Data Service)客户端操作精粹

在有了System.Data.SQLite和ADO.NET Data Service为我们打好的基础之上,我们可以把它们合璧在一起,发挥更大的作用。类似的观点,ccBoy也有论述——Astoria to SQLite to Entity Framework to 建立你的ORM观念。以我这两天的实践来看,最大的优点如下:

  • 通过使用System.Data.SQLite简化服务器端的部署,尤其数据库的部署。就算使用SQL Server 2005/2008 Express的数据库文件的方式,也会遇到权限(或一些莫名其妙)的问题。
  • 通过使用ADO.NET Data Service简化数据库的访问,在客户端可以直接编写LINQ查询,而不必局限于于自定义WCF访问接口。也不会遇到实体关系处理在Client和Server端的不同问题。

当然,要很好的利用这两把利剑,需要注意如下事项(以我的实践而言):

  1. 安装:在开发机器和部署服务器上都安装SQLite-1.0.65.0-setup.exe。就我的情况而言,开发机器上,会自动添加GAC,而服务器上需要手动添加GAC。并且奇怪的是开发机器上,有MSIL、x86和AMD64的版本,而在服务器上只能添加x86和AMD64的版本。System.Data.SQLite和System.Data.SQLite.Linq都需要添加。如果在服务器上不添加GAC,那么在服务器上运行,会提示不能加载程序集(我猜想是因为System.Data.SQLite.DLL内部合并了sqlite的引擎)。
  2. 开发:通过VS的数据库管理器,在sqlite中添加表等。然后新建一个Entity Data Model,把表添加到EDM中。新建一个ADO.NET Data Service的服务,修改关联的ObjectContext。配置config.SetEntitySetAccessRule。
  3. 配置:编译配置就AnyCPU。(之前我遇到一些问题,查看资料说有可能需要设定为x64或x86,不过由于我的开发机器和服务器都是64的,所以应该不是这个问题。相应解释:http://www.cnblogs.com/downcom/archive/2009/10/26/1590120.htmlhttp://sqlite.phxsoftware.com/forums/t/1970.aspx,所以如果你的开发机器和服务器是不同位的话,需要考虑这种情况)。需要在config文件中添加(在readme中其实有讲到):

    <system.data>
       <DbProviderFactories>
         <remove invariant="System.Data.SQLite"/>
         <add name="SQLite Data Provider" invariant="System.Data.SQLite" description=".Net Framework Data Provider for SQLite" type="System.Data.SQLite.SQLiteFactory, System.Data.SQLite" />
       </DbProviderFactories>
    </system.data>

  4. 部署:部署应该不会有什么大问题,主要是db文件应该让当前的运行用户(一般是Network Service)对其具有读写权限。

我也上传了我实践的示例代码(其中包含了用于测试EF功能的EFQuerySamples),从这里下载

在这个示例中,也包含了如何获取明细数据的方式,有两种:

  1. LoadProperty方式(即Explicit loading):在选中主表中某条数据的时候,在加载当前对象的明细表属性,如:dc.LoadProperty(c,"Orders");
  2. Expand方式(即Eager loading):在载入主表数据的时候,就提前载入明细表的数据

Update(2009-12-28):经过我的实验,Data Service并未对LoadProperty方法进行缓存,每次调用这个方法都是要请求服务器,这样处理其实也合理;而Expand方式,在第一次启动的时候载入所有数据,也会很慢。所以我建议:主表数据少,而明细表数据多的时候,采用LoadProperty方式;而主表数据多,而明细表数据少的时候,对主表分页并使用Expand方式来加载明细表。

posted @ 2009-12-27 14:58  朱永光  阅读(3005)  评论(3编辑  收藏  举报