EF概要
Entity Framework概要
Entity Framework是微软的Object Relational Mapper(对象关系映射器),也就是我们平常说的ORM,它可以让应用程序开发者将关系型数据作为业务模型来使用,也消除了开发者为数据访问编写的绝大多数管道代码的需要(比如使用ADO.NET)。Entity Framework提供了一个综合的、基于模型的系统,通过摆脱为所有的领域模型编写相似的数据访问代码,使得开发者创建数据访问层是如此之简单。Entity Framework的首发版本是EF3.5,是伴随着.Net Framework 3.5 SP1和VS 2008 SP1一同发布的。从那之后,EF已经进化了很多很多,当前版本是6.1.3
Entity Framework通过开启数据访问和将数据表示为概念化模型(即一系列的实体类和关系)减轻了创建数据访问层的任务。应用程序可以执行基本的CRUD操作,以及轻松地管理实体间的一对一,一对多和多对多关系。
下面是使用Entity Framework的一些好处:
- 因为开发者不需要为数据访问编写所有需要的ADO.NET管道代码,因此这可以节省很多开发时间。
- 我们可以使用更高级的语言(例如C#)来编写所有的数据访问逻辑而不是编写SQL查询和存储过程。
- 因为数据库表没有高级的关系(如继承),然而领域实体是可以有的,所以业务模型(也就是概念模型)可以使用实体间的关系来适配应用领域。
- 底层的数据存储可以相对轻松地被取代,因为所有的数据访问逻辑都呈现在应用层而不是数据层。
现在通过一张图看一下EF的架构:
从这张图上可以看到,EF是建立在ADO.NET框架之上的,它下面仍旧使用了ADO.NET方法和类来执行数据操作。
Entity Framework简史
多年来,有许多ORM工具进入市场,有开源的,也有商业的。微软也开发了自己的ORM工具。第一个是内置于.Net 3.5的LINQ to SQL。该ORM仅支持
SQL Server和SQL Server Compact。2008年第一次发布的Entity Framework是第二次尝试,相较于LINQ to SQL有很多优点。首先,有自己的provider架构,因此对于所有的关系数据库引擎都是开放的,而不仅仅是SQL Server。现在所有的主要RDBMS都有Entity Framework provider。
Entity Framework经历了很多版本。
第一版只支持Database First。这意味着你要将设计器指向一个已存在的数据库,然后就会生成一个包含数据库和表抽象的代码。除了代码之外,还会创建一个EDMX文件,该XML文件包含了实体数据模型(因此你也就知道了EDMX的意思了Entity Data Model Xml)。它包括三个模型:逻辑,存储和映射。逻辑模型(有时也叫概念模型)就是使用C#进行编码的那个,存储模型描述了数据是如何存储到数据库中的,映射模型提供了逻辑模型和存储模型之间的映射。如果你在数据库中更改了东西,那么你也要更新生成的模型,C#代码也要再次生成。映射模型有一个基于ObjectContext
的类,该类有数据库中每张表的集合属性,每个集合都是一个泛型集合,集合中的元素类型是从EF中的一个基类中继承的。每个类都有属性和相应的数据表中的列对应。
第二版,也就是EF4,也开始支持Model-First了。这样 ,我们就可以使用设计面板创建实体类,然后设计器会产成SQL脚本来生成数据库。对于这种方法,仍会生成EDMX文件,最终的结果是和Database First是相同的。
最后,EF的Code First在版本4.1中引入。Code First不需要EDMX文件了,每个实体也不需要从EF的基类中继承了。这样,代码变得更加容易测试。这种方法也不需要依赖设计器了,你只需要编写类就行,而且它们会自动地映射到数据库中的表。当前的EF 6.1.3中的Code First已经相当强大了。
Entity Framework具有的能力
EF对于微软开发者可以做很多事情。
首先,它可以将数据库暴露成对象的集合,这是通过利用很多关键的类完成的。前提是你要了解DbContext
,这个类是EF Code First的核心,在高层次上是数据库抽象。数据库包含了表,每个表又包含了行和列。DbContext有泛型集合属性,每个属性的类型是DbSet<TRowType>
对应于每个表。集合中的每个对象指的是一个实体,代表相应表中的一行。数据表中的列是定义在TRowType
类中的属性。
一旦这个结构布局好了,那么你就能够通过LINQ查询来查询底层的数据库了。如果你将一个全新的TRowType
类的实例添加到父集合中,然后使用DbContext API保存更改,那么这个新的对象就会变成相应表中的一行,该对象的每个属性的值就会变成该行相应的列值。此外,EF有能力表示其他的数据库工件,比如存储过程和函数。数据库结构的进化是很重要的一个问题,在大多数情况,随着应用程序的变化,你需要添加列和表,EF是通过Migration(迁移)功能来解决这个问题的。这个能力允许你通过C#代码更改数据库结构,除了添加和删除表和列之外,还可以添加索引。Migration可以没有数据损失地进化数据库模式。你将会看到,EF会暴露你需要使用C#访问的一切数据而不需要编写SQL,并且像对待你整个应用程序代码的一部分来对待数据库。你可以将migration代码迁入到源代码控制系统(Git/SVN)中,因为它也是C#代码!
Entity Framework的架构
EF构建在provider架构之上。当开发者使用C#创建一个LINQ查询时,EF框架引擎会连接一个provider,将它转换成实际的SQL语句,最后发往数据库。任何给定的provider都是连接Entity Framework和一个特定的RDBMS的桥梁。一旦该provider执行了最终的SQL命令,结果就被EF物质化到.NET对象中。Data reader就是为了这个目的。理解EF构建于ADO.NET之上非常重要,因此,EF也使用了诸如connection,command,和data reader的概念。谈到数据持久化,也就是插入,更新和删除功能,插入时,开发者将一个实体类的实例添加到数据库上下文中。相似地,之前添加到上下文中的实例被标记为changed或deleted,就会产生对数据库即将执行更新和删除的语句。EF会检查上下文中的每个对象,再次使用provider来创建RDBMS特定的insert,update,或delete命令。
Entity Framework的三种开发风格
- Database First:这是一种用于已存在数据库模式的方法。使用这种方法,EDM是从数据库模式中生成的,这种方法最适合于使用了已经存在的数据库的应用。
- Code First:这种方法中,所有的领域模型都是以类的形式编写的。这些类会建立我们的EDM,数据库模式会从这些类中创建。这种方法最适合于那些高度以领域为中心并且领域模型类创建优先的应用程序。这里需要的数据库只是为了这些领域模型的持久化机制。
- Model First:这种方法和Code First方法很相似,但是这种情况下我们使用了EDM视觉设计器来设计我们的模型。数据库模式和类将会通过这个概念模型生成。该模型将会给我们创建数据库的SQL语句,然后我们可以使用它来创建数据库并连接应用程序。
三种风格的比较
Database First
主要的好处就是:如果数据库已经存在了,那么只需要花一点时间就可以编写数据访问层。EDM可以从数据库中生成,然后根据需求更改EDM。
一些场景:
- 对遗留的数据库进行开发
- 当其他团队的DBA完成了数据库设计时,一旦数据库完成,应用开发就要开始
- 当要开发数据为中心的应用时,应用领域模型就是数据库本身,数据库会频繁修改来满足新的需求。
Model First
和Database First相似,Model First最终以EDM结束。使用该EDM,我们可以创建概念模型和数据库。使用这种方法的唯一原因就是我们真的想要使用视觉实体设计器。
Code First
Code First对于所有的业务逻辑以类实现,并且数据库只用作这些模型的持久化机制时很有用。
选择Code First的一些原因:
- 数据库只是作为模型的持久化机制,即数据库中没有逻辑。
- 完全控制代码,即没有自动生成的模型和上下文代码。
- 数据库不会手动更改。模型类总是更改,然后数据库基于模型类的更改而更改。
如何选择持久化方法
上面介绍了三种选择,至于选择哪一种,这也是个不大不小的问题,那么请参考下面进行决定: