[Programming Entity Framework] 第1章 ADO.NET实体框架介绍(二)
Programming Entity Framework 第二版 翻译索引
后端数据库:你来选择
你可能注意到我还没提及实际用于数据查询的数据存储。模型对于数据存储一无所知,它是什么类型的数据库,更不用说是什么构架。它也不需要知道这些。
你后端选择的数据库对于你的模型或者你的代码没有一点影响。
EF与ADO.NET已经使用的ADO.NET数据提供者沟通,但是有一个前提。提供者必须更新能支持EF。提供者在重新形成EF的查询和命令到本地查询和命令中参与。你所需要做的就是确定提供者和数据库连接串,这样EF能进入数据库。
这意味着如果你想让应用程序能工作于多个不同的数据库,你不用学习每个数据库的插入和读取。你可以使用EF的语法写查询(LINQ to Entities或者Entity SQL),而不用担心数据库之间的差别。如果你想使用某个数据库的函数或操作,Entity SQL允许你做同样的事。
数据库提供者
微软包含在VS 2008 SP1和VS2010中的SqlClient APIs支持EF。它允许你使用SQL Server 2000, 2005和2008。你可以使用完整版或试用版的2005和2008,还有完整版的2000。注意实体数据模型设计器不能与Sql Server2000交互。这不是EF的设计限制,而是VS2010本身。VS的工具都不能识别SQL Server 2000。然而,EF运行时可以。SQL Server CE 3.5和4版本也都支持EF。查询2010年7月7号SQL Server CE组发表的这篇关于SQL Server Compact 4的文章http://blogs.msdn.com/sqlser
Vercompact。
在这本书编写的同时,其它的提供者也能获得,更多的还在开发中,它们将允许你使用Orcale,IBM数据库,SQL Anywhere, MySQL, SQLite, VistaDB及其它的数据库。提供者由数据库供应商及第三方供应商编写。其中大部分基于.net 3.5编写。有一个很重要的特性直到他们更新到.net 4才能支持,那就是模型优先(model first),这个你将在第25章学习到。
Access和ODBC
能支持EF的提供程序需要对它要连接的数据库的类型有明确的认识。必须知道数据库可用的函数和操作符,还有针对本地查询的的正确语法。开放式数据库连接提供程序为很多数据库提供了通用的存取。其中包括Access数据库,它不能为与EF的交互提供数据库结节。因此,ODBC不是EF合法的提供程序。除非某人为Access创建明确的提供程序,否则你不能使用EF与之交互。微软也没有计划 为Access创建提供程序,因为了它的需求量太低。
实体框架(EF)特性:APIs和工具
除了EDM,EF提供了一系列.NET运行时APIs允许你使用EDM编写.net应用程序。它也包括一系列设计模型的设计工具。下面是EF主要特性的概要。
元数据
虽然EF设计的是让你直接到EDM的类工作,它仍然需要同数据库交互。EDM描述的概念数据模型存储在XML文件中,它的构架指定了实体及他们的属性。在EDM的概念构架描述的背后是另一对XML文件,它映射数据模型到数据库。一个是描述数据库的XML文件,另一个提供了概念模型与数据库间的映射。
在查询和命令(例如更新)执行时,EF计算出如何将数据模型中的查询或命令的表达转化成数据库的表达。它通过读取元数据实现。
当数据从数据库返回时,它使用元数据将数据库结果转成实体和更进一步的格式化对象。
EF通过代码优先(code first)特性获取使用内存模型的能力,它是EF社区技术预览的一部分。它还不是EF的组成部分,必须分开下载。代码优先允许你单独与类工作,需要的XML构架在运行时飞速写入内存。你将在第25章学习更多这个特性,但是请注意在这本书出版的时候代码优先仍然是CTP,没有完全开发出来。
实体数据模型设计工具
图表1-2和1-3都是从EDM设计器中截图出来的。它是VS的一部分,为用户提供了可视化编辑模型的方式,而不用直接面对XML。在第2章中你将学习到正确使用设计器的方法,同时在第14章学到如何使用它做更高级的模型,例如继承。第25章学习模型优先设计。你将了解到设计器的限制,例如它不支持EDM的所有特性。某些EDM不常用到的特性,你必须直接编辑XML文件。在第2 章,你将看到XML文件,及它如何如你在设计器中看到的相关连,这样在第15章它改变时,你将对原生的构架文件有所熟悉。
在vs2010中,设计器比vs2008 sp1支持更多的特性。然后,在第14和15章中,你将看到仍然有一部分特性需要手工修改。
设计器也允许你映射存储过程到实体中,这将在第6章中讲到。如果你用过vs2008 sp1,你会发现在vs2010中设计器对于存储过程的支持有很的改进和提高。
另一个值得一提的特性是它允许你从数据库更新模型,添加你之前没用到的数据库对象或在模型之后添加到数据库的对象。
数据库优先设计
EDM设计器的一个工具是实体数据模型向导。它允许你指向现存的数据库并从它直接生成模型,这样你不用从头开始。一旦你有了第一版的模型,你可以开始在设计器自定义模型了。
模型优先设计
并不是所有的开发都从现有的数据库开始。Vs2010的一个新特性是直接在设计中创建模型然后基于该模型生成数据库构架的能力。虽然在本书中我们关于使用数据库优先设计创建模型,你还是有机会练习模型优先设计及一其它一些设计特性,在第25章中。
代码生成
一旦你有了定义业务实体的模型,你就需要有在运行时代表它们的类。设计器能够为了从模型自动生成这些类。然后,我们在vs2010中有另一个重要的特性。与在vs2008 sp1使用属性代码生成器不同,类全部由vs的文本模板转化工具包(T4)生成。它不光为代码生成提供了常用的机制,同时你可以更容易的自定义提供的模板以定义你想要从模型中生成的类。你将在第11章中学习代码生成能力,然后在后面的章节中更深入的学习T4的自定义。某些场景下你可以跳过全部的代码生成,仅使用你自己的类。
对象服务
EF在运行时最显著的特性,也是你在工作时最常遇到的,就是对象服务。对象服务在EF堆的最上面,如图1-6所示,它提供与基于实体的对象工作必要的功能。对象服务提供被称为EntityObject的类,它很容易管理从EntityObject继承的任何类。这包括为将查询结果格式化为基于EDM的对象,跟踪这些对象的变化,管理它们的关系及保存改变到数据库。
在查询和更新之间,对象服务提供了与实体对象交互的宿主主能力,例如与自动与低层的EF工作,为调用数据库做必需的工作和处理结果。对象服务也提供了序列化(XML和库)。
POCO支持
.NET 4最重要的运行时增加特性是EF管理不从EntityObject继承的实体的能力。这是EF新的POCO(Plain Old CLR Objects)支持,你将在第13章学习到这个特性。POCO支持对于允许多样的编辑风格非常重要。有了POCO实体,开发人员可以更空间的创建单元测试和持久化未知的实体类。这些能力对于遵循领域驱动和敏捷开发的代码规范的开发人非常重要。这些同样在.NET 3.5的EF中不可用。现在EF拥抱更广阔的开发社区。
变化追踪
一旦实体对象实体化,不管是做为从查询中返回的结果还是在代码中新创建的对象,对象服务能保持对该对象的追踪。这个对于从查询中返回的对象是默认的。当对象服务管理对象时,它保持对对象属性或它与其它实体对象关系变化的追踪。
对象服务然后在更新数据时使用变化追踪信息。它通过比较实体的当前与原始值,构建每个对象(增加,修改或删除的)的Insert, Update, Delete命令。如果你使用实体间的存储过程,它将传递当前值(原始值特别地指定)给这些存储过程。
关系管理及外键
关系是EDM危险的部分;然后在.net 4中,一个重要的新特性被加进来了:外键支持。在经典的实体关系模型中,外键在概念模型中没有被暴露。EF在.NET 3.5 SP1中采用了这种范式。但是我们的开发人员由于多种原因仍然希望能存储这些外键值。事实上,在本书的第一版中,我提供了一系列获取和设置外键的办法。现在EF在概念模型中支持外键。然后,为向后兼容缺乏外键这一特性,你仍然可以使用之前的机制将关系实例化为对象。
在本书中我将不会花太多时间关注采用旧的方式创建关系,因为它不是默认的,并且使用较少。如果你更深入的指导,如果在概念模型中缺乏外键时如何工作。我推荐你本书的第一版。
正如你将发现的,特别是在第19章,它就关系讲的更为深入,即使有了外键,你也必须对关系如何工作有非常好的理解。一些与相关的数据工作的约定并不直观,如果你打破这些规则,你可以写代码抛出异常或错误。第19章为EDM提供了深入理解,这样你能以专家的方式同它工作。
数据绑定
你可以在很多数据绑定场景中使用实体。在Windows Forms和WPF,你可以使用实体作为数据绑定控件或绑定源控件的数据源,它在窗口中为对象和UI控件提供绑定。第9章提供一个很好示例,使用实体对绑定源控件进行编辑和更新数据。第26章关注从用户界面中分离数据存取和其它业务逻辑层,以提供为应用程序提供更好的架构。
第9章也提供了WPF应用程序的实体数据绑定示例。VS2010介绍了WPF数据绑定的很多增加,当使用实体绑定数据时你将从中受益很多。
对于ASP.NET,有名叫EntityDataSource的数据源控件,它与ASP.NET的SqlDataSource和LinqDataSource控件类似,允许你申明绑定实体对象到界面上。第12章就是关于使用 EntityDataSource的。你将在那一章快速获取使用ASP.NET 动态数据的绑定。
N层开发
EF为在.net 3下的N层开发做了重大的进步。在.net 3.5 SP1中,它太难了;同样地,在本书的前一个版本,我花了很大篇幅致力于变通的做法。现在我们不仅能从外键中获益,还能从状态管理中得到回转,它使用处理过得变得简单。另外,POCOs使得N层开发更容易实现,这你将在本书的后续章节中看到。
对于分层应用程序,第24和25章专注于将数据存取任务从ASP.NET用户界面中分开,你会看到WPF应用程序,ASP.NET Web Form应用程序,还有ASP.NET MVC应用程序,使用不同的模式分离逻辑。
实体客户端
实体客户端是EF中另一个主要的API,尽管你很少与它直接打交道。它为与数据库的存储过程和命令(与数据库提供程序结合)工作提供必要的功能,执行命令,从过程中获取结果,将它格式化为与EDM匹配的结果。
你可以直接与实体客户端工作,或者与它顶端的对象服务工作。不光是因为它可以执行查询,更因为它这样是代表了对象服务。差别在于当你直接用实体客户端时,你得到的是列表数据结果(虽然这些数据可以被转化)。如果你用对象服务,它会把实体客户端创建的数据转化成对象。
由实体客户端返回的列表数据是只读的。实体客户端非常合适报表和将数据从一个持久化转移到另一个。只有对象服务提供变化追踪及将变化保存回数据存储的能力。
实体框架和WCF服务
你可以在能使用ADO.NET的任何地方使用EF,包括web服务和WCF服务。第17和18章中将带你处理为EntityObject实体和POCO实体提供服务。
在这些章节中,我们也会看一下WCF数据服务,WCF RIA服务,被称为自追踪实体的特定的POCO模板,它对实体提供客户端的变化追踪能力,因此允许一种简单的方式将变化发送给WCF服务,然后持久化它们到数据库。
ADO.NET数据集和LINQ to SQL怎么样?
EF只是ADO.NET堆最新的增加物。它是如何影响现有的使用DataSets和DataReaders或者LINQ to SQL的代码的呢?你可以使用这些技术继续写新的代码吗?
DataSets
DataSet和DataReader不会消失。所有的现存的投资会继续工作,你仍然可以使用这些技术存取数据并做交互。EF提供了一种完全不同的方式来存取数据。你不需要集成这两种技术,例如,使用EF查询一些数据,然后将它装进DataSet;完全没必要。你可以使用它们中任一个。正如你所了解的EF,你发现它提供了完全不同的方式存取数据。你可能发现EF适合某些项目,但是其它的,你可能仍然希望使用DataSets。
EF也以EntityDataReader的形式使用了DataReader,它也是同SqlDataReader一样继承自DbDataReader。它就是EntityClient查询返回的东西。事实上,你会发现使用EntityClient查询EDM的代码看起来与你直接使用ADO.NET查询数据库的代码非常相似。它使用连接,命令,命令参数,返回DbDataReader,你可以使用任何你能使用的DataReader,例如SqlDataReader,从它那读取数据。
在Ef中不可用的一些ADO.NET工具是查询通知和 ASP.NET SqlCacheDependency。另外,ADO.NET SqlBulkCOpy需要DataReader或者DataSet将数据以流的形式存入数据库。EF没有与ADO.NET DataAdapter.BatchUpdate相对等的东西,因此,当EF保存变化到数据库时,它一次只能发送一个命令。
LINQ to SQL
LINQ to SQL和EF在表面看起来很相似。他们都使用数据模型提供了基于数据库的LINQ查询。
一个常被问到的问题是:为什么微软创建两个相似的技术?LINQ to SQL从LINQ工程中进化而来,它来自于语言开发组。EF是数据编程组的工程,它关注于实体SQL语言。等到这两种技术成熟时它在微软向其它组展示,很明显微软有两个非常棒的技术,它们可以应用于不同的场景中。EF组使用LINQ与实体工作,它让开发更加困扰因为LINQ to Entities和LINQ to SQL看起来很像。
LINQ to SQL 最终引入到微软的数据程序组,2008年11月该组发表了申明因为技术解决同一样的问题,他们会专注于开发EF,支持多样数据库并且与微软即将使用实体数据模型的技术看齐。然而,他们会继续维护增强LINQ to SQL。这对于使用LINQ to SQL的开发人员不是一个乐观的形势。微软承诺维护ADO.NET中的LINQ to SQL,并没有发表申明放弃它。它也承诺会提供LINQ to SQL到EF的迁移,并推荐在未来的开发当中使用EF替代LINQ to SQL。
实体框架(EF)的痛处正在消失
在本书的第一版中,第1章列出了两页痛苦的地方。当时的标题是"EF设计器"(它关注于缺少对存储过程及其它EDM特性的支持),"分布式应用程序变化追踪的挑战","领域驱动开发"和"单元测试"。感谢.NET 4和vs2010的改进,我很高兴移除了这些章节。
然而,还是大量无用的地方需要关注。模型会从例如支持唯一的外键,表格值功能,增强的多对多关系中获益,一个最主要的问题是:对于大模型的支持。
EF的状态管理和关系管理仍然还有许多不直观的行为,如果你不仔细研究,它很有可能咬你一口。请查看第19章获取一个不错的研究指导。
本书花费了大量时间深入研究了EF的运行时,向你展示一些限制,尝试指出一些不平坦及遗漏的地方。
更成熟的ORM工具用户继续对EF提供抱怨,例如提供内部交互的难处(数据库转移,然后是支持的)。但是如果你纵观市场,甚至是EF最强烈的竞争对手都开始提供与EF工作的高级工具。最主要的对手,Nhibernate,为EF创建了非常完美的数据库设计,LLBL Gen Pro已经为EF创建了强大的设计器,它为管理EFEDM和它的元数据提供了不同的方法。
使用EF编程
当你通览本书时,你会获得设计EDM和使用EF编写应用程序的经验,还有深入理解API,学习如何操作实体对象及基于它们行为的一般性控制。很多功能都是可理解的,也有很多隐藏的能力。你将学习到背后有什么,这样你会意识到EF真实的益处。
甚至在我全神贯注于这个版本的Programming Entity Framework,我期待框架的未来版本,因为它是在持续演化的。
本博客已不再更新,欢迎访问新地址