Entity Framework

✍ dations ◷ 2024-12-23 00:26:15 #.NET

Entity Framework (又称ADO.NET Entity Framework) 是微软以 ADO.NET 为基础所发展出来的物件关联对应 (O/R Mapping) 解决方案,早期被称为 ObjectSpace,现已经包含在 Visual Studio 2008 Service Pack 1 以及 .NET Framework 3.5 Service Pack 1 中发表。

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

长久以来,程序员和数据库总是保持着一种微妙的关系,在商用应用程序中,数据库一定是不可或缺的元件,这让程序员一定要为了连接与存取数据库而去学习 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),让资料存取的工作得以顺利与完整的进行。

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

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

<?xml version="1.0" encoding="utf-8"?><Schema Namespace="Employees" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">  <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) 所撰写。

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

<?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) 所撰写。

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

<?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>

查询对象

ADO.NET 实体数据模型工具会产生从 ObjectContext (代表概念模型中所定义的实体容器) 派生而来的类别。 ObjectContext 类别支持针对将实体当成对象传回之概念模型进行查询,也支持创建、更新和删除实体对象。 Entity Framework 支持针对概念模型进行对象查询。 这些查询可以使用 Entity SQL 、Language-Integrated Query (LINQ) 和对象查询产生器方法来撰写。

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

// 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();}

LINQ to Entities

实现 IEnumerable<T> 泛型接口或 IQueryable<T> 泛型接口的数据源可以透过 LINQ 进行查询。 实现泛型 IQueryable<T> 接口之泛型 ObjectQuery<T> 类别的运行个体会当做 LINQ to Entities 查询的数据源。 ObjectQuery<T> 泛型类别表示传回零个或多个具类型对象之集合的查询。 使用 C# 的 var 关键字 (在 Visual Basic 中为 Dim),您也可以让编译器推断实体类型。

using (AdventureWorksEntities AWEntities = new AdventureWorksEntities()){    ObjectQuery<Product> products = AWEntities.Products;    // LINQ Query syntax:    IOrderedQueryable<Product> query =        from product in products        orderby product.Name, product.ListPrice descending        select product;    // LINQ Method syntax:    IOrderedQueryable<Product> query = products        .OrderBy(product => product.Name)        .ThenByDescending(product => product.ListPrice);}

查询产生器方法

ObjectQuery 类别支持对概念模型进行 LINQ to Entities 和 Entity SQL 查询。 ObjectQuery 也会实现一组查询产生器方法,这些方法可用来循序建构与 Entity SQL 相等的查询命令。由于 ObjectQuery 会实现 IQueryable 和 IEnumerable,所以将 ObjectQuery 所实现的查询产生器方法结合 LINQ 特定的标准查询运算符方法 (如 First 或 Count) 是可行的。 LINQ 运算符并不会传回 ObjectQuery,与查询产生器方法不同。

// 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));

开发工具

目前 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 亦可由Windows记事本等文本编辑器所编辑。

微软特别针对了网络上各种不同的应用程序(例如 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:

相关