对象/关系映射框架

ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案。该框架曾经为.NET Framework的一部分,但version 6之后从.NET Framework分离出来。

简介

ADO.NET Entity Framework 以 Entity Data Model (EDM) 为主,将数据逻辑层切分为三块,分别为 Conceptual Schema, Mapping Schema 与 Storage Schema 三层,其上还有 Entity Client,Object Context 以及 LINQ 可以使用。

ADO.NET Entity Framework 建模

Entity Framework 技术的应用中 ,可针对数据库中各个表按照1:1 映射生成模型和映射信息 ,在代码中直接对表中数据进行增、删、改、查操作,但在实际应用中,这种简单的处理方式不利于进一步降低程序开发工作量,部分情况还违背了“程序开发以应用为中心的概念模型来工作”的理念 ,对象的概念不清晰。为此 ,对几种常用的数据库情景的建模方法进行介绍 [1]  。

带有有效载荷的多对多关系建模

在带有有效载荷的多对多关系数据库中,关系表除了主键外,还有其他数据字段。在这种关系中,直接把表映射到实体模型中,两实体表自动创建对应的实体类型,而关系表也被映射成为一实体类型,在此实体类型中除了原有属性名,还有对应两实体表的导航属性,可分别通过1对多关系进行对象导航。

自引用关系建模

对于分类表之类的自引用表 ,把表映射成为实体类型后 ,其中将包含两个导航属性 分别对应父、子对象 ,其中父对象为 1 端 ,多端为子对象集合 ,因此分别把 1 端改名为父端名称如Parent Category,多端改名为子对象集合名称如 Sub Categories。由此两导航属性可方便地访问到对应对象。

跨表实体建模

在数据库设计过程中 ,当一个实体的数据由于各种原因为分割在不同表中 ,而程序开发需要把实体所有数据集合在一个实体类型中。对于这种跨表实体的情况 ,建模时首先把所有的表都映射到实体模型中 ,然后调整实体类型 ,把主要表之外的其它表映射实体类中除主键对应属性外的所有属性复制到主要表映射实体类型中 ,然后删除主要表映射实体类型中的所有导航属性和其它表实体类型 ,在删除其它表实体类型时 ,不删除映射存储模型中

的表 ,最后 ,在剩下的这一个表映射实体类型中 ,添加复制得到的所有属性的映射关系 ,分别映射到对应的表中的列。在实体操作过程中 ,映射关系能自动分别处理不同表中的对应数据。

多实体建模

在表中如果有部分字段内容较多并且不常使用 ,为提高程序性能 ,访问表时,一般只访问表中的部分字段, 为此 ,建模时必须把表分割成多个实体。首先把表映射成一般实体类型 ,然后在设计器中创建新实体类型 ,添加对应原表中主健的属性 ,再把原映射实体类型中不需要的属性通过“剪切 / 粘贴”方法移动到新实体类型中 ,并把新实体类型中的所有属性映射到原表对应字段 ,然后在原实体类型中添加到新实体类型的 1对1(或 1 对 0.1)关联关系 ,最后 ,在添加以新实体类型为主体的到原实体类型的引用约束。通过实体类型访问数据时 ,两实体类型对象分别访问其属性对应的字段数据。

多表派生建模

数据库建模完成后 ,对于有些表存储另一表中额外信息的情况 ,可以针对这些表建立派生的类体系结构。首先,把所有表映射到实体模型中,分别映射成一个实体类型 ,然后删除实体类型之间的关联,再为基类(Business)添加继承 ,分别设置派生类为Retails 和 e Commerces,再删除派生类中的 Business Id 属性 ,则根据表的结构完成类的体系结构建模 ,对 Retails 和 e Commerces 类型对象的操作会自动访问库表 Retails、e Commerces 及对应的 Business表中对应记录。

表分割建模

对于常见的办公自动化系统数据库 ,由于员工类型不同 ,而薪水制度不同 ,其中 Employee Type 值为 1 则为临时工 ,薪水按小时计算 ,Wage 字段记录其每小时薪水 ,Salary 字段为无效 数 据 ,如 果 Employee Type 值 为 2 则 为 正 式 员 工 ,薪 水 按 月计算 ,Salary 字段记录其每月薪水 ,Wage 字段数据无效。为更好地实现向应用编程 ,分别建立临时工和正式员工两种类型 ,但两种类型的数据都保存在 Employees 表中。建模过程首先把 Employees 表映射到实体模型中 ,成为 Employees 类 ,然后添加新实体 Hourly Employee,指定基类为 Employees,然后通过“剪切 / 粘 贴 ” 把 Employees 中 的 Wage 属 性 移 动 到 Hourly Employee中 ,用 同 样 的 方法添加实体 Full Time Employee 类型;再在Hourly Employee 实体中 ,添加映射条件 :“Employee Type = 1”,在Full Time Employee 实体中添加映射条件 :“Employee Type = 2”,然后设置 Employees 类型为抽象类,并删除其中的 Employee Type 属性,则Hourly Employee和Full Time Employee自动处理 Employee Type 字段的值 ,并能自动根据记录创建对应类型的对象。

版本信息

ADO.NET Entity Framework自.NET 3.5以来就被集成于.NET中,最新版本是Entity Framework 6.1.3。

版本

支持.NET

发布情况

备注

Entity Framework 3.5

2.0+

包含于.NET 3.5中

支持EDMX生成,通过扩展可支持POCO类的生成

Entity Framework 4.0

4.0+

包含于.NET 4.0中

Entity Framework 4.X

4.0+

可通过NuGet获取

支持Database First、Model First、Code First三种生

成模式

Entity Framework 4.5

4.5+

集成于.NET 4.5中

Entity Framework 5.X

4.5+

可通过NuGet获取

支持枚举字段,性能有较大提升,支持.NET 4.0的版本

为Entity Framework 4.4

背景

ADO.NET Entity Framework 架构图

长久以来,程序设计师和数据库总是保持着一种微妙的关系,在商用应用程序中,数据库一定是不可或缺的元件,这让程序设计师一定要为了连接与访问数据库而去学习 SQL 指令,因此在信息业中有很多人都在研究如何将程序设计模型和数据库集成在一起,对象关系对应 (Object-Relational Mapping) 的技术就是由此而生,像Hibernate或NHibernate都是这个技术下的产物,而微软虽然有了ADO.NET这 个数据访问的利器,但却没有像NHibernate这样的对象对应工具,因此微软在.NET Framework 2.0发展时期,就提出了一个ObjectSpace的概念,ObjectSpace可以让应用程序可以用完全对象化的方法连接与访问数据库,其技术概念 与NHibernate相当类似,然而ObjectSpace工程相当大,在.NET Framework 2.0完成时仍无法全部完成,因此微软将ObjectSpace纳入下一版本的.NET Framework中,并且再加上一个设计的工具(Designer),构成了 ADO.NET Entity Framework。

Entity Framework 利用了抽象化数据结构的方式,将每个数据库对象都转换成应用程序对象 (entity),而数据字段都转换为属性 (property),关系则转换为结合属性 (association),让数据库的 E/R 模型完全的转成对象模型,如此让程序设计师能用最熟悉的编程语言来调用访问。而在抽象化的结构之下,则是高度集成与对应结构的概念层、对应层和储存层,以 及支持 Entity Framework 的数据提供者 (provider),让数据访问的工作得以顺利与完整的进行 [2]  。

(1) 概念层:负责向上的对象与属性显露与访问。

(2) 对应层:将上方的概念层和底下的储存层的数据结构对应在一起。

(3) 储存层:依不同数据库与数据结构,而显露出实体的数据结构体,和 Provider 一起,负责实际对数据库的访问和 SQL 的产生。

架构

概念层结构

概念层结构定义了对象模型 (Object Model),让上层的应用程序码可以如面向对象的方式般访问数据,概念层结构是由 CSDL (Conceptual Schema Definition Language) 所撰写。

一份概念层结构定义如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<?xml version="1.0" encoding="utf-8"?>

<Schema Namespace="Employees" Alias="Self" xmlns="ADO EDM Version 0.0">

<EntityContainer Name="EmployeesContext">

<EntitySet Name="Employees" EntityType="Employees.Employees" />

</EntityContainer>

<EntityType Name="Employees">

<Key>

<PropertyRef Name="EmployeeId" />

</Key>

<Property Name="EmployeeId" Type="Guid" Nullable="false" />

<Property Name="LastName" Type="String" Nullable="false" />

<Property Name="FirstName" Type="String" Nullable="false" />

<Property Name="Email" Type="String" Nullable="false" />

</EntityType>

</Schema>

对应层结构

对应层结构负责将上层的概念层结构以及下层的储存体结构中的成员结合在一起,以确认数据的来源与流向。对应层结构是由 MSL (Mapping Specification Language) 所撰写2。

一份对应层结构定义如下所示:

1

2

3

4

5

6

7

8

9

10

11

<?xml version="1.0" encoding="utf-8"?>

<Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">

<EntityContainerMapping StorageEntityContainer="dbo" CdmEntityContainer="EmployeesContext">

<EntitySetMapping Name="Employees" StoreEntitySet="Employees" TypeName="Employees.Employees">

<ScalarProperty Name="EmployeeId" ColumnName="EmployeeId" />

<ScalarProperty Name="LastName" ColumnName="LastName" />

<ScalarProperty Name="FirstName" ColumnName="FirstName" />

<ScalarProperty Name="Email" ColumnName="Email" />

</EntitySetMapping>

</EntityContainerMapping>

</Mapping>

储存层结构

储存层结构是负责与数据库管理系统 (DBMS) 中的数据表做实体对应 (Physical Mapping),让数据可以输入正确的数据来源中,或者由正确的数据来源取出。它是由 SSDL (Storage Schema Definition Language) 所撰写3。

一份储存层结构定义如下所示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

?xml version="1.0" encoding="utf-8"?>

<Schema Namespace="Employees.Store" Alias="Self"

Provider="System.Data.SqlClient"

ProviderManifestToken="2005"

xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">

<EntityContainer Name="dbo">

<EntitySet Name="Employees" EntityType="Employees.Store.Employees" />

</EntityContainer>

<EntityType Name="Employees">

<Key>

<PropertyRef Name="EmployeeId" />

</Key>

<Property Name="EmployeeId" Type="uniqueidentifier" Nullable="false" />

<Property Name="LastName" Type="nvarchar" Nullable="false" MaxLength="50" />

<Property Name="FirstName" Type="nvarchar" Nullable="false" />

<Property Name="Email" Type="nvarchar" Nullable="false" />

</EntityType>

</Schema>

用户端

当定义好 Entity Data Model 的 CS/MS/SS 之后,即可以利用 ADO.NET Entity Framework 的用户端来访问 EDM,EDM 中的数据提供者会向数据来源访问数据,再传回用户端。

ADO.NET Entity Framework 有三种用户端4:

Entity Client

Entity Client 是 ADO.NET Entity Framework 中的本地用户端 (Native Client),它的对象模型和 ADO.NET 的其他用户端非常相似,一样有 Connection, Command, DataReader 等对象,但最大的差异就是,它有自己的 SQL 指令 (Entity SQL),可以用 SQL 的方式访问 EDM,简单的说,就是把 EDM 当成一个实体数据库。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// Initialize the EntityConnectionStringBuilder.

EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();

//Set the provider name.

entityBuilder.Provider = providerName;

// Set the provider-specific connection string.

entityBuilder.ProviderConnectionString = providerString;

// Set the Metadata location.

entityBuilder.Metadata = @"res://*/AdventureWorksModel.csdl|

res://*/AdventureWorksModel.ssdl|

res://*/AdventureWorksModel.msl";

Console.WriteLine(entityBuilder.ToString());

using (EntityConnection conn = new EntityConnection(entityBuilder.ToString()))

{

conn.Open();

Console.WriteLine("Just testing the connection.");

conn.Close();

}

Object Context

由于 Entity Client 太过于制式,而且也不太符合 ORM 的精神,因此微软在 Entity Client 的上层加上了一个供编程语言直接访问的界面,它可以把 EDM 当成对象般的访问,此界面即为 Object Context (Object Service)。

在 Object Context 中对 EDM 的任何动作,都会被自动转换成 Entity SQL 送到 EDM 中执行。

1

2

3

4

5

// Get the contacts with the specified name.

ObjectQuery<Contact> contactQuery = context.Contact

.Where("it.LastName = @ln AND it.FirstName = @fn",

new ObjectParameter("ln", lastName),

new ObjectParameter("fn", firstName));

LINQ to Entities

Object Context 将 EDM 的访问改变为一种对对象集合的访问方式,这也就让 LINQ 有了发挥的空间,因此 LINQ to Entities 也就由此而生,简单的说,就是利用 LINQ 来访问 EDM,让 LINQ 的功能可以在数据库中发挥。

1

2

3

4

5

6

using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())

{

ObjectQuery<Product> products = AWEntities.Product;

IQueryable<Product> productNames =

from p in products

select p;

开发工具

ADO.NET Entity Framework 的开发,在 Visual Studio 2008 中有充份的支持,在安装 Visual Studio 2008 Service Pack 1 后,文件范本中即会出现 ADO.NET 实体数据模型 (ADO.NET Entity Data Model) 可让开发人员利用 Entity Model Designer 来设计 EDM,EDM 亦可由记事本或文本编辑器所编辑 [3]  。

派生服务

主条目:ADO.NET Data Services

ADO.NET Entity Model Designer

微软特别针对了网络上各种不同的应用程序 (例如 AJAX, Silverlight, Mashup 应用程序) 开发了一个基于 ADO.NET Entity Framework 之上的服务,称为 ADO.NET Data Services (项目代号为 Astoria),并与 ADO.NET Entity Framework 一起包装在 .NET Framework 3.5 Service Pack 1 中发表。

支持厂商

有数个数据库厂商或元件开发商宣布要支持 ADO.NET Entity Framework:

(1) Core Lab,支持Oracle、MySQL、PostgreSQL 与 SQLite 数据库。

(2) IBM,实现 DB2 使用的 LINQ Provider。

(3) MySQL,发展 MySQL Server 所用的 Provider。

(4) Npqsql,发展 PostgreSQL 所用的 Provider。

(5) OpenLink Software,发展支持多种数据库所用的 Provider。

(6) Phoenix Software International,发展支持 SQLite 数据库的 Provider。

(7) Sybase,将支持 Anywhere 数据库。

(8) VistaDB Software,将支持 VistaDB 数据库。

(9) DataDirect Technologies,发展支持多种数据库所用的 Provider。

(10) Firebird,支持 Firebird 数据库。

EF(ADO.NET Entity Framework)相关推荐

  1. 利用泛型与反射更新实体(ADO.NET Entity Framework)

    自从ADO.NET Entity Framework面世以来,受到大家的热捧,它封装了大量代码生成的工具,用户只需要建立好实体之间的关系,系统就是会为用户自动成功了Add.Delete.CreateO ...

  2. EF(Entity FrameWork)实体框架

    一. 1.简称:实体框架 2.ADO.NET Entity FrameWork 是微软以ADO.NET为基础发展出来的对象关系对应(O/R Mapping)解决方案: 3.ORM框:对象关系映射(Ob ...

  3. NHibernate与EF(Entity Framework)的区别

    概述 长久以来,程序员和数据库总是保持着一种微妙的关系,在商用应用程序中,数据库一定是不可或缺的元件,这让程序员一定要为了连接与访问数据库而去学习 SQL 指令,至少对于我而言,我觉得这是一个很不爽的 ...

  4. ADO.NET Entity Framework 学习(1) [ZT]

    前一段时间园子里有很多文章介绍分析了Linq To SQL,它可以说是一个简单实现的ORM,是微软针对数据和对象的阻抗不平衡的问题.C# 3.0推出一些新的特性,比如Extension Method, ...

  5. ADO.NET Entity Framework Beta2(五)/快速入门(实体框架)

    This quickstart illustrates a series of tasks that support the topics in Getting Started with the En ...

  6. ADO.NET Entity Framework 入门示例向导(附Demo程序下载)

    ADO.NET Entity Framework 入门示例向导(附Demo程序下载) ADO.NET Entity Framework 是.Net Framework 3.5 SP1 引入的实体框架, ...

  7. ADO.NET Entity Framework -Code Fisrt 开篇(一)

    ADO.NET Entity Framework 是微软的一套实体映射框架.发布EF4.1(Entity Framework )时,又提出了代码先行的设计理念(the code comes first ...

  8. ADO.NET Entity Framework 学习(1)

    前一段时间园子里有很多文章介绍分析了Linq To SQL,它可以说是一个简单实现的ORM,是微软针对数据和对象的阻抗不平衡的问题.C# 3.0推出一些新的特性,比如Extension Method, ...

  9. 转载:ADO.NET Entity Framework 试水系列索引(2008/9/9更新,本系列结束)

    Visual Studio 2008发布时,微软给我们带来了LinQ to SQL,解决所谓"阻抗不匹配"问题.最近,随着Visual Studio 2008 SP1的正式发布,又 ...

最新文章

  1. 浅谈电量传感器在数据中心的UPS电源中的应用
  2. 用《叩响C#之门》复习C#基础知识 第八章 面向对象编程:类和对象(二)
  3. springboot 读取配置文件_使用 @ConfigurationProperties 在 Spring Boot 中加载配置
  4. 高考英语口试计算机系,大学英语口语考试都考什么,高考英语口试考什么?
  5. 二叉树中的最大路径和
  6. spring学习(47):bean的作用域
  7. ORA-01502 state unusable错误成因和解决方法[转]
  8. c form画直线_新手教程跟我一起画儿童裤子裁剪图
  9. linux内存利用率多少合适,如何理解linux服务器中的内存使用率和平均负载
  10. 解决VsCode中C程序无法键盘输入的问题
  11. UDP报文观测以及DNS的工作原理
  12. r语言 tunerf函数_R语言非参时间序列(六):波动脉冲响应(VIR)中的关键公式推导...
  13. ea6700梅林固件
  14. 使用高德地图API获取天气
  15. java unhandled,Unhandled Exception thrown: class java.lang.ClassCastException
  16. java造成capturing lambda后需要注意的事情
  17. java等待所有子线程执行完毕再执行
  18. Python实现数字转人民币(大写汉字)源代码
  19. C语言 输出三角形数列 for循环
  20. JavaScript单选框选择操作

热门文章

  1. 手机界面操作-隐藏url地址栏
  2. 微信新功能「微信指数」 大数据、小程序
  3. 练习8-8 移动字母 (10分)
  4. 基于VMD分解算法,可用于信号分解,故障诊断,数据预测和分类等研究领域
  5. linux字符串转为整型,C语言将字符串转换为整数
  6. Node.js:浅析高并发与分布式集群
  7. mysql and和or
  8. tag开发实例源代码
  9. 基于XGBOOST模型预测货物运输耗时 - Part 2 通过方差分析了解文本型变量与数值型目标变量的关系
  10. 2022-2028全球硅胶疤痕凝胶产品行业调研及趋势分析报告