Entity Framework的存储模型切换实践

【本文选自微软MVP林立的博客】最近做一个项目,里面需要同时支持SQL Server和SQLite。考虑到Entity Framework虽然目前还有诸多不足,但是基本上满足于我的项目的要求,加上,也希望做一个尝试,毕竟,虽然使用过去的技术和手段可能更可靠、更熟练、风险更低。

作者简介:

林立,微软ASP.NET与C# MVP,专注和热衷于将.NET平台下较为成熟的新技术实践于实际项目开发,近期着重于研究Entity Framework和Windows Workflow Foundation。

[[8789]]

但是,在技术行业,不能止步不前,如果某种新技术有你需要的某些特性,并且你认为值得尝试,那就应该出手试试,虽然尝试可能会失败(以及不得不吞下失败产生的苦果),但是如果成功,其带来的好处也是很大的,也代表着你又往前迈进了一步。对于Entity Framework我也是新手,如果各位朋友发现文中有什么可以改进的地方或者不正确的地方,欢迎指点。

废话不多说了,切入正题。Entity Framework需要三种文件支持:CSDL(概念架构定义语言)、SSDL(存储架构定义语言)、MSL(映射规范语言),以及,一个据此生成的类文件(这里我们不研究这个类文件)。从这种结构上看,EF是完全支持上层稳定的概念架构与底层具体可变动的存储架构之间的独立和分离的。但通常我们利用VS的设计器只能生成一个单独的.edmx文件,其中包含了CSDL、SSDL和MSL的内容,而本质上,它们3个是完全可以独立成3个文件的。对于我们当前的目标,我们需要把SSDL从.edmx文件中剥离出来,并创立分别针对于SQL Server和SQLite的SSDL,下面详述一下我的做法。

1、根据SQL Server中的表、视图结构,创建SQLite数据库

由于之前已经SQL Server上已经有了相关的表和视图,因此以Sql Server为模板,创建SQLite数据库,并在SQLite数据库中创建与SQL Server中的表和视图几乎完全一样的表和视图。之所以说“几乎完全一样”,是因为SQLite中的类型系统与SQL Server中的差别很大。但是因为我没有用到SQL Server中太特别的类型,因此这个问题的解决相对容易一些。我从SQL Server中生成表和视图的脚本,然后修改一下让SQLite可以识别和执行。

主要的修改包括,去掉“dbo”架构的指定,将自增标识列主键的声明“int identity(1,1) primary key”改为“integer primary key autoincrement”,后者是SQLite中自增列主键的声明语句,对于其他简单类型,比如varchar/nvarchar, bit, money等等类型则保留原有的声明不变,这些类型虽然SQLite并不“支持”,但是执行的时候并不会出错,而且利用“.schema”命令查询表架构时,这些类型的声明是被保留的(后面在生成针对SQLite的EDM的时候,似乎也说明这些类型声明产生了正面作用),另外,有一点,这次我没有用到DateTime类型,因此无法断定2种数据库对它的支持的差别。SQLite的类型系统的特点是,动态性,虽然你创建表的时候可以指定某种“类型”,但是你完全可以向一个“int”列插入一个字符串。最后,我没有在SQLite中创建任何外键约束,虽然SQLite支持外键,但是为了简化复杂性(毕竟这是我的初次尝试),就牺牲一些“完整性”吧。由于保证了SQLite中的表和视图与Sql Server中的完全一致(除了类型上的固有差别),因此,可以保证两者在创建EDM的时候,其CSDL和MSL是完全相同的。

2、依据SQL Server创建EDM

具体方法就和我们平常做的一样。利用VS比较强大的设计器,从SQL Server中生成模型,并且创建好各个实体之间的Association。经过这一步,我们会得到一个.EDMX文件以及一个对应的类文件。

3、创建针对SQL Server的SSDL文件

用XML编辑器打开上面生成的.EDMX文件,可以很清楚的分辨出SSDL、CSDL、MSL三部分。我们把“<edmx:StorageModels>”节点下的<Schema>节点的所有内容Copy出来,然后新建一个后缀名为.SSDL的XML文件,把Copy出来的Schema元素粘贴进去,保存,就可以了。

4、创建针对SQLite的SSDL文件

这一步有2种办法:将针对SQL Server的SSDL文件复制一份过来,然后将其修改成符合SQLite的要求。主要是去掉一些SQLite不支持的东西,比如,对于Schema=”dbo”这样的声明。以及,修改Schema元素的Provider属性和ProviderManifestToken属性。前者需要修改为”System.Data.SQLite”,后者修改为“ISO8601”(为何改成这2个值?看到后面就会知道了)利用VS的设计器重新针对SQLite数据库生成一份EDMX文件,然后抽取其中的SSDL定义。

我采用的是第二种方法:这里需要用到针对SQLite的ADO.NET提供程序,即System.Data.SQLite。这个东西真正的下载地址在http://sourceforge.net/projects/sqlite-dotnet2/files/。

下载完成之后,可以安装,然后就可以在项目中引用System.Data.SQLite并利用设计器创建针对SQLite数据库的EDM。创建和提取SSDL的内容与针对SQL Server的完全一样,不再赘述,由此,我们可以得到一个针对SQLite的SSDL文件,其中Schema元素的Provider属性值是System.Data.SQLite,而ProviderManifestToken属性是ISO8601。

这里还需要指出的一点是,后来在测试的时候,发现运行失败,原因是,在SSDL中存在不同的表/实体类型中引用和被引用的字段(外键字段)Type属性不一致的情况,比如假设Company类型的CompanyID字段在Company类型中的type是integer,但是在引用它的Employee类型中的CompanyID字段的type是int,在这里,比如把它们2个统一为int或integer才可以。

5、通过修改连接字符串来切换不同的SSDL

在我的项目中,我将这2个SSDL分别作为2个不同的程序集的资源内嵌到程序集中。然后通过修改连接字符串来切换到某个SSDL。连接字符串看起来是这样的:

 

  1. metadata=res://GE/GTDP.GTDEDM.csdl|res://LiteTDP/LiteTDP.GTDEDM.ssdl|res://GE/GTDP.GTDEDM.msl;  
  2. provider=System.Data.SQLite;  
  3. provider connection string=&quot;  
  4. Data Source=D:\Practice\SQLite\Ricky.db;&quot。 

注意连接字符串中对于CSDL、SSDL、MSL的指定,都指定到具体程序集的相关资源,其中黄色底色部分指定了使用SQLite的SSDL,而CSDL和MSL则直接使用了第二步中生成的EDMX中的内容。

补充:

在第二步中生成的EDMX被完整的保留下来,这样,仍然可以随时利用设计器打开和操作。而针对SQLite生成的EDMX在提取需要的SSDL之后被我删掉了。当然了,是留是删,完全看需要,很久没有写东西,都不会说话了,如果读起来别扭,请多包涵了。

本文转载自零度的火的博客,

原文地址:http://www.cnblogs.com/Ricky81317/archive/2010/02/22/1670867.html

【编辑推荐】

  1. 关系数据库的根本问题分析及数据库革命之走向
  2. 探寻关系数据库和ORM的最佳替代者
  3. 数据库机时代将到来 DBA面临新挑战
  4. 分布式缓存系统Memcached入门指导
  5. 扔掉沉没成本 尝试关系数据库替代品OODBMS

 

 

【责任编辑:王晓东 TEL:(010)68476606】

 

 

文章来源网络,作者:管理,如若转载,请注明出处:https://shuyeidc.com/wp/275868.html<

赞 (0)
管理的头像管理
上一篇2025-05-10 09:42
下一篇 2025-05-10 09:44

相关推荐

  • jsp空间购买和交换数据空间怎么买,有哪些注意事项?

    购买JSP空间时,是否考虑过数据交换空间的性能?简米科技(2003年始创,23年行业沉淀)与酷番云(工信部一类增值电信全牌照)这类持牌自营机房的服务商,能确保数据交换的高效稳定,是值得优先选择的合作伙伴,为什么JSP空间需要搭配独立的数据交换空间从JSP应用特性看数据交换需求JSP基于Java技术,常用于企业级……

    2026-08-11
    0
  • 建网站用香港空间效果怎么样,香港空间稳定吗?

    建网站用香港空间,对于创建网站资产来说,核心价值在于免备案和全球带宽优势,尤其适合外贸、跨境电商和需要快速启动的项目,但你必须权衡国内访问延迟,并选择有资质的服务商以保证资产安全,香港空间的核心优势与适用边界免备案:节省时间就是节省成本国内服务器需要备案,通常需要10到20天,香港空间无需备案,域名解析后即可上……

    2026-08-11
    0
  • Java连接云数据库的方法是什么,如何操作

    Java连接云数据库的核心在于通过JDBC驱动,结合云服务商提供的连接地址、端口、数据库名及认证信息,配置安全策略(如SSL、IP白名单),即可实现稳定高效的远程数据库访问,基础准备:JDBC驱动与依赖管理连接云数据库前,需要确保开发环境具备对应的JDBC驱动,以最常见的MySQL为例,你需要引入mysql-c……

    2026-08-11
    0
  • 建网站公安联网备案必须使用数据码吗,备案流程是什么

    网站备案包括ICP备案和公安联网备案,两者缺一不可,公安联网备案必须使用服务商提供的数据码,选择持有合法资质的服务商是顺利通过备案的前提,为什么网站必须进行公安联网备案根据公安部《计算机信息网络国际联网安全保护管理办法》,网站开通后30日内必须到公安机关办理备案手续,未完成公安备案的网站,面临责令整改、关闭网站……

    2026-08-10
    0
  • 建一个企业网站大概需要多少钱?,怎么收费?

    建网站要多少钱,没有一个固定的数字,几百到几万都可能,但真正的“创建网站资产”绝不仅仅是初次投入的成本,而是基于长期稳定、合规和安全的持续性投入,其中核心取决于你选择了什么样的“地基”来承载你的业务,建站预算的构成与行业基准当你开始规划一个网站,最先面对的就是预算问题,一个常见的误区是只关注网站“看起来”的建造……

    2026-08-10
    0

发表回复

您的邮箱地址不会被公开。必填项已用 * 标注