EF是微软为建立应用程序而提供数据访问技术,同VS一起,提供一个广泛的,基于模式的生态系统,使用户能够开发种类繁多的面向数据的应用程序。

历史

    EF可以追溯到VS2008,版本有EF1;VS2010有EF4.0,EF4.1-EF4.3;VS2012经历了EF5和EF6;VS2015的EF版本现在是6.1.3. EF7正在开发中...

    附VS2012/2013 EFTools6.1.3下载链接https://www.microsoft.com/en-us/download/details.aspx?id=40762。如果在VS2012/2013中数据模板内未找到ADO.NET EDM模板的话,可以下载该工具进行安装。


The Model(EDM模型)

    EF专门用来建模。使用EF建模,会发现很多同以前技术和模式(pattern)类似的标记。比如类似的实体关系图表,一些概念、逻辑以及物理设计分层方法。

    EF中生成的模型由一个叫做EDM(Enity Data Model)的概念表示,EDM使我们可以通过强类型的实体类而不是数据库的架构和对象进行编码。EDM使你能够在实体类和数据库表之间自定义映射,这种映射超越了传统的一对一、类对表的映射。

wKiom1ZVPZbxCE2wAAF8ITwDkiY060.png

    上图中,数据库并没有直接映射到实体类。相反,EDM中提供的映射功能使开发人员使用更贴近应用程序域的实体类进行编码,与之对应的是以性能、伸缩性和可维护性为目的的高度标准化数据库设计。

    举例来说,从DBA角度看,上图中Employee、Devices和Phone被物理存储在3张表中。但开发人员通过单个包含一个Devices集合和Phone的Employee实体进行编码。从开发人员和项目利益相关者(一般来讲就是关键用户)的角度看,一个employee就是单个对象。开发人员不知道也不关心DBA将employee标准化为3张不同的数据库表。当然这需要进行额外的配置,一旦配置完成,单个类和3个数据库表的映射就由EF抽象并控制。

    Department表和Accounting、Marketing、Finance3个实体之间的映射是一个相反的情况,3个实体映射到同一张表,也需要进行额外的配置。

    当然最简单的方式是实体和数据库表是一一映射,这也是EF的默认行为。

    总之,开发人员及项目关键用户使用的是与应用程序上下文相关的域类,DBA则创建后台数据库表,使其更高效、易扩展和易维护。最后使用EF将它们关联起来。

The Layers(EDM层级)

    EDM包含3个独立的层:概念层、存储层和映射层,3个层级间是相互独立的。

    实体类都包含在EDM的概念层中,这个层也是开发人员和关键用户所涉及的。取决于EF的具体实现,概念层可以通过设计器或者直接在代码中建模。既可以借助EF提供的工具利用逆向工程从现存的数据库进行建模;或者先建模,然后使用EF生成数据库,以此衍生出来的6.1.3版本的4种模型:基于数据库的EF设计器模型、基于数据库的Code-First模型以及空的EF设计器模型和空的Code-First模型。概念层的语法定义在CSDL(Conceptual Schema Definition Language)。

    存储层定义需要映射到基础数据库中的表、列、关系和数据类型。存储层的语法被SCDL(Store Schema Definition Language)定义。

    映射层定义概念层和存储层之间的映射。映射层定义实体的属性映射到数据库表中的列。映射层为开发人员在EF设计器中提供了一个映射详细信息(Mapping Details)窗口。如果开发人员使用基于代码的方法,那么映射层也提供了数据标注(data annotations)和fluent API方法。MSL(Mapping Specification Language)定义了映射层的语法。

术语

    EntityType(实体类型):EntityType表示域模型中的一个类。EntityType的一个实例通常指的是一个entity(实体)。如果使用EF设计器,EntityType被显示为设计界面的一个带多个属性的方框。

下图显示2个实体类型:Employee和Task

wKioL1ZXxLehwDXjAAGiu-M00zk881.png

    Property(属性):一个实体类型通常有一个或多个属性(property)。实体类型的属性同类(class)类似,它是一个有着特殊数据类型的并被命名值。属性既可以是简单类型(simple type),像int,string等等,也是可以是复合类型(complex type),甚至是集合。导航属性(Navigation proprety)引用到其他相关实体,通常表示为关系数据库中的外键引用。实体类型中的非导航属性通常称为标量属性(scalar property)。

    Association(关联):两个实体间的关系通常叫做关联(association)。在设计界面上,实体类型的关联通常为一条连接实体类型的线。线的两端通常被标注以表示关联各端的重度(multiplicity)。上图就显示了Employee和Task之间1对多的关联。一个employee能有1个或多个task,一个task关联并仅关联到一个employee.

    EntityKey(实体键):每一个实体类型都有一个属性或属性集(多个属性)表示实体类型的实体键(EntityKey)。实体键唯一标识EF中的实体,并且经常映射为实体类型所表示的后台数据库的主键。

    Context object(上下文对象):上下文对象是EF服务的网关,它揭示实体对象,管理数据库连接,生成参数化SQL语句,整理需要存储到数据库的和从数据库取出的数据,缓存对象,协助维护改变追踪和实例化或转换一个无类型的结果集到一个强类型对象的集合。

    DbContext:EF最开始的时候,上下文对象是ObjectContext对象。现在EF使用一个更精简的上下文对象叫做DbContext。DbContext极大的简化了开发人员使用EF的开发过程。有趣的是,DbContext是ObjectContext的封装器,DbContext也提供后台ObjectContext的功能。

The Code(代码)

    尽管EF一再强调它的可视化支持,但实质上EF的一切都是代码相关的。模式、实体类型、关联、映射等等最后都会表示为应用程序中具体的代码。代码要么被VS和EF生成或者被手动产生。可以选择大量使用代码生成处理(code-generation process)或者通过改变项目中的各种属性而完全不用它或者修改后台代码生成模板。

    VS使用一种代码生成技术叫做T4(Text Template Transformation Toolkit)模板。MSDN关于T4的链接:https://msdn.microsoft.com/en-us/library/bb126445.aspx。

    另外,还可以使用最新的代码优先(Code-First)方法手动编写具体的代码以实现对整个过程的直接控制。使用Code-First,开发人员不需要使用设计器就能产生实体类、映射和上下文对象。手动生成的实体类通常指的是POCO(Plain Old CLR Object),没有引用EF。现在EF6.1.3也提供“来自数据库的Code-First”方法。

VS

    VS提供一个EF建模的整合设计界面。使用这个设计界面和VS提供的其他工具,可以从头开始或者从已存在的数据库中生成模型。也可以完全不用设计器而是手动生成实体类型和配置。

    VS也提供工具导入现有数据库的表和关系到模式。另外,也可以从头开始产生一个模型,从一个空的设计界面开始,添加实体类型,配置关联和继承层次。模型生成后,通过在设计界面上点击右键,选中“根据模型生成数据库”命令,根据向导提示生成相应的数据库。

    如果项目是以代码为核心的,则可以先生成一系列的实体类,以及它们的关系,加上一个上下文类,然后直接将它们同EF的引擎和特性关联起来。

    模型生成后,可能会经常发生改变。VS提供工具可以从数据库更新模式(通过设计界面上下文菜单中的“从数据库更新模型”);也可以通过工具Code-First Migrations将模型的更改同步到数据库。