五月 22, 2009

Entity Data Model 资料大杂烩

Written by

    新项目启动伊始,程序框架、接口与逻辑、数据存储,可扩展性、可维护性、实现的简单性,等等等等,总是讨论最热烈的话题。前车之鉴,后世之师,多看看,多想想

    下面是一些为项目做准备而看的一些有用的资料,收集于此,便于查阅

 

关注ADO.NET Entity Framework

来自:一代芒果–asp.net技术

 

    有消息称微软将会放弃linq to sql转向ADO.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 可以使用。

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

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

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

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

 

一、目前开发工具

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

二、支持厂商

目前已有数个数据库厂商或元件开发商宣布要支持 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 数据库。

 

关注ADO.NET Entity Framework

 

网址:http://blog.csdn.net/uuwish/archive/2009/04/13/4069042.aspx

 

 

Entity Framework 架构简介

The Entity Framework looks like a interesting technology which is more powerful and advanced than LINQ to SQL. Both technologies have a different kind of philosophy but several features have similar implementations. The EF is more than just an ORM (Object Relational Mapping) tool. It allows developers to query and manipulate data using a conceptual model instead of a physical storage model.

The ADO.NET Entity Framework is a layered framework which abstracts the relational schema of a database and presents a conceptual model.

Data Source : The bottom layer is the data which can be stored in one or many databases.

Data Providers : The data will be accessed by a ADO.NET data provider. At this moment only SQL Server is supported but in the near future there will be data providers for Oracle, MySQL, DB2, Firebird, Sybase, VistaDB, SQLite, …

Entity Data Model (EDM) : The Entity Data Model consists of 3 parts :

  • Conceptual schema definition language (CSDL) : Declare and define entities, associations, inheritance, … Entity classes are generated from this schema.
  • Store schema definition language (SSDL) : Metadata describing the storage container (=database) that persists data.
  • Mapping specification language (MSL) : Maps the entities in the CSDL file to tables described in the SSDL file.

Entity Client : EntityClient is an ADO.NET managed provider that supports accessing data described in an Entity Data Model. It is similar to SQLClient, OracleClient and others. It provides several components like EntityCommand, EntityConnection and EntityTransaction.

Object Services : This component enables you to query, insert, update, and delete data, expressed as strongly-typed CLR objects that are instances of entity types. Object Services supports both Entity SQL and LINQ to Entities queries.

Entity SQL (ESQL) : Entity SQL is a derivative of Transact-SQL, designed to query and manipulate entities defined in the Entity Data Model. It supports inheritance and associations. Both Object Services components and Entity Client components can execute Entity SQL statements.

LINQ to Entities : This is a strong-typed query language for querying against entities defined in the Entity Data Model.

下图是来自微软MSDN的中文图片资料,表示了ADO.NET Entity Framework 体系结构:

Source URL:
http://www.scip.be/index.php?Page=ArticlesNET12

 

 

ADO.NET Entity Framework简介

作者:Ring    时间:2008-08-31 

下一代的ADO.NET的目标是要解决关系数据模型和实际应用程序需要模型之间的鸿沟,那么它是怎么做到的呢?

我们都知道,建立在关系数据库基础之上的应用程序经常需要在不同的表之间做复杂的join操作来取得相关的数据。

比如下面的例子:

           [图1] 

这是一个普通的关系型数据库。这个结构主要描述了雇员的基本信息和雇员的销售情况。

假如我们想取得所有在2006年1月1日招聘过来的全职员工的姓名和职务信息,那么就需要写如下的sql查询语句:

1SELECT c.FirstName, e.Title
2FROM Employee e
3INNER JOIN Contact c ON e.EmployeeID = c.ContactID
4WHERE e.SalariedFlag = 1 AND e.HireDate >= 2006-01-01
5

我们分析一下这个复杂的sql语句,就会发现它存在如下缺点:

1. 如果某个应用程序只处理Employees的信息,但我们必须将逻辑数据关系标准化。这样我们就不得不去关注数据库表与表之间的关系(比如雇员的联系信息和姓名在不同的表中),我们需要人为地在两个表中做内联交叉查询以得到正确的数据。
2. 这里该应用程序仅仅是处理全职雇员(SalariedFlag=1),理想的情况是,我们不应看到其他类型的雇员信息。然而实际上所有的雇员信息都在一个数据库表中,他们是用一个”SalariedFlag”字段来区分的。这就意味着我们需要关注如何将不同类型的雇员加以区分。理想的情况是这样的:假如我们只需要处理某个数据子集,系统只需要呈现这部分子集的数据。开发人员应当能够通过声明来指定哪个是需要的数据子集。

综合地说,首先,关系数据模型不能直接匹配应用程序实际的数据模型。其次,关系数据模型不能满足应用程序的实际需要,比如应用程序还需要一些非功能性的需求,这些需求包括操作,数据拥有关系,性能和安全。

为了解决如上问题,ADO.NET引入了Entity Framework,它包含了数据模型以及一些设计时和运行时的服务。通过Entity Framework提供的更高抽象层,应用程序的数据模型就可以直接和数据库的关系数据模型交互。

Entity Data Model

Entity Data Model—简称EDM—是一个实体关系数据模型(Entity-Relationship data model). EDM的一个关键的概念如下:

Entity: Entity是实体类型的实例(例如:Employee, SalesOrder)。它由一个关键字来组织数据记录。多个Entity可以组成Entity-Sets.

RelationShip:RelationShip是关系类型的实例,它关联相关的实体.多个Relationships 可以组成 Relationship-Sets.

除了上面两个核心概念外,EDM模型还支持多种类型的扩展.

继承:实体类型可以继承于其他的类型.这种类型的继承只继承结构,不提供向面向对象语言的"行为"继承.

复合类型:定义一个复合类型Address,它可以由StreetAddress, City 和State这些属性复合而成.

我们按照EDM的概念重新定义[图1]:

             [图2]
这里描述了如下元素:
三个实体类型,分别是SalesPerson,SalesOrder和StoreSalesOrder。其中StoreSalesOrder继承自SalesOrder。
一个关系: SalesOrder 和 SalesPerson 之间的关系。
两个实体集(entity-sets):SalesOrders 和 SalesPeople。 实体集SalesOrders 拥有SalesOrder和StoreSalesOrder两个实体类型。

看看上面的模型视图已经更接近应用程序需求了。其中SalesPerson的信息已经不再分布在不同的数据表中了,同时也没有了主从键了。

比如以前这样的查询:

1SELECT sp.FirstName, sp.LastName, sp.HireDate
2FROM SalesPerson sp
3INNER JOIN Employee e ON sp.SalesPersonID = e.EmployeeID
4INNER JOIN Contact c ON e.EmployeeID = c.ContactID
5WHERE e.SalariedFlag = 1 AND e.HireDate >= 2006-01-01
6

现在只需写成:

1SELECT sp.FirstName, sp.LastName, sp.HireDate
2FROM SalesPeople AS sp
3WHERE sp.HireDate >= 2006-01-01

更多关于ADO.NET Entity Framework相关的介绍, 英文好的朋友可以参阅:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnvs05/html/ADONET_EDM.asp
以及
http://msdn.microsoft.com/data/default.aspx?pull=/library/en-us/dnvs05/html/ADONETEnFrmOvw.asp

 

 

 

 

ADO.NET Entity Framework

维基百科,自由的百科全书

跳转到: 导航, 搜索

ADO.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) 的技术就是由此而生,像HibernateNHibernate都是这个技术下的产物,而微软虽然有了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),让数据存取的工作得以顺利与完整的进行。

  • 概念层:负责向上的对象与属性显露与存取。
  • 对应层:将上方的概念层和底下的储存层的数据结构对应在一起。
  • 储存层:依不同数据库与数据结构,而显露出实体的数据结构体,和 Provider 一起,负责实际对数据库的存取和 SQL 的产生。

架构

概念层结构

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

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

<?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) 所撰写[2]

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

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

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

?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 当成一个实体数据库。

// 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 中运行。

// 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 的功能可以在数据库中发挥。

using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
ObjectQuery<Product> products = AWEntities.Product;
IQueryable<Product> productNames =
from p in products
select p;
}

开发工具

ADO.NET Entity Model Designer

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

派生服务

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

  • Core Lab,支持Oracle、MySQL、PostgreSQL 与 SQLite 数据库。
  • IBM,实现 DB2 使用的 LINQ Provider。
  • MySQL,发展 MySQL Server 所用的 Provider。
  • Npqsql,发展 PostgreSQL 所用的 Provider。
  • OpenLink Software,发展支持多种数据库所用的 Provider。
  • Phoenix Software International,发展支持 SQLite 数据库的 Provider。
  • Sybase,将支持 Anywhere 数据库。
  • VistaDB Software,将支持 VistaDB 数据库。
  • DataDirect Technologies,发展支持多种数据库所用的 Provider。
  • Firebird,支持 Firebird 数据库。

参考资料

外部链接

整合 ADO.NET Entity Framework 到應用程式中

作者:朱明中

架構考量

ADO.NET Entity Framework 是連接應用程式和資料庫之間的介面層,可將原本相當耗工的資料存取與物件對應(O/R Mapping)部份簡化成只需要能夠應用 LINQ 或 Object Service 就可以順利存取資料庫,對資料庫的應用程式開發人員來說,是一個相當棒的技術,而且由於 O/R mapping 被做掉,讓開發資料層物件的開發人員可以省下很多工夫,有更多的時間,可以回去陪女友或老婆。

若是一個全新的應用程式,可以很順理成章的利用 Entity Framework 來加速應用程式的開發,不過若是要在已經存在的應用程式中套用 Entity Framework 的話,就要有所計畫與考量了。在多數的企業應用程式中,都會分成數個元件層次(Layered Components),與資料庫較有關的資料存取,都套用在資料存取層(DALs)或是資料存取元件(DACs)中,然後由 Business Components(企業邏輯元件)和資料存取層溝通以讀寫資料庫中的資料,然後把執行結果交給 Presentation 來顯示使用者介面。

在資料存取層中,可以分成幾種設計方法:

  • 由程式碼負責資料存取:使用 ADO.NET 元件連接與存取資料庫,資料庫中只有資料表與檢視表。
  • 由程式碼和 DBMS 共同負責資料存取:使用 DBMS 中的功能(例如資料庫物件),併同 ADO.NET 存取資料庫中的資料。
  • 由 DBMS 負責資料存取:使用 DBMS 中的功能,設計一個存取介面,應用程式則用 ADO.NET 連接到 DBMS 中的存取介面以存取資料。

在商業邏輯層中,要視資料存取層的設計法,來決定商業邏輯層的設計方法:

  • 資料存取元件負責做 O/R Mapping:直接取用資料存取元件中的物件來讀寫資料。
  • 資料存取元件只回傳 DataRow/DataTable/DataSet:由商業邏輯層做 O/R Mapping,要花的工會比較多一點。

針對不同的應用程式架構做考量,才能夠有效的整合 ADO.NET Entity Framework 到正確的位置,並且發揮最多的效率。

架構整合

我們在前面幾篇中所提到的技術,各有適用的層面:

技術 適用位置 說明
Entity Client 資料存取 與 ADO.NET 物件相似,在初學 ADO.NET Entity Framework 時可以利用。
Entity SQL 資料存取 DBA 或習慣使用 SQL 存取資料之開發人員可以利用。
Object Service 資料存取
商業邏輯
支援 Entity SQL,適合於商業邏輯(程式碼)或資料存取層之用。
LINQ to DataSet 商業邏輯 若資料存取層回傳 DataSet 或 DataTable 時,可改寫商業邏輯層,使用 LINQ 來查詢。
LINQ to SQL 資料存取
商業邏輯
將資料存取層交給 DBMS,或者在資料存取層做 O/R Mapping,再用商業邏輯在讀寫資料存取層。
LINQ to Entities 商業邏輯 在商業邏輯層中讀寫 Entity,由 Entity 來做為資料存取層。

開發人員可以透過技術的選擇,來將 Entity Framework 整合到應用程式中,而不同的發展方式也會影響技術的選擇:

  • 資料存取層中:
    技術 套用技術 說明
    由程式碼負責資料存取 Entity SQL
    Object Service
    產生 Entity Data Model,然後用 Object Service 存取。
    由程式碼和 DBMS 共同負責資料存取 LINQ to Entities
    Object Service
    Entity SQL
    產生 Entity Data Model,然後用 Object Service 或 LINQ to Entities 存取。
    由 DBMS 負責資料存取 LINQ to SQL 直接連接與存取 DBMS。
  • 商業邏輯層:
    技術 套用技術 說明
    資料存取元件負責做 O/R Mapping Object Service
    LINQ to Entities
    LINQ to SQL
    直接取用資料存取元件中的物件來讀寫資料。
    資料存取元件只回傳 DataTable/DataSet LINQ to DataSet 直接利用 LINQ 存取來自資料存取元件的 DataTable/DataSet。

整合實例 A:將 DAL(資料存取層)以 Entity Model 取代

例如,一般在資料存取層中可能會寫像這樣的程式碼(備註,以下的整合實例都採用相同的程式碼):

public static DataTable GetProductList(string Category)
{
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand(
“SELECT * FROM ProductInfo WHERE CategoryID = @catID”, conn);
SqlDataAdapter adapter = new SqlDataAdapter (cmd);
DataTable table = new DataTable()
adapter.Fill(table);
conn = null;
cmd = null;
adapter = null;
return table;
}

<>而商業邏輯層可能會寫這樣的程式碼(O/R mapping 做在商業邏輯層的建構子函式):

DataTable table = DataService.GetProductList(categoryID);
List<ProductInfo> productList = new List<ProductInfo>();
foreach (DataRow row in table.Rows)
productList.Add(row[“ProductID”].ToString(), row[“Caption”].ToString(), …);

在套用 Entity Framework 後,若是直接使用資料庫建立 Entity 的話,DAL 可以直接以 Entity Model 取代,而商業邏輯層可以改寫為:

var query = from p in db.ProductInfo
where p.CategoryID == categoryID
select p;
// output product list to List<T> collection.
List<ProductInfo> productList = query.ToList();
// access objects.
foreach (var r in query)
productList.Add(p.ProductID, p.Caption, …);

直接套用 Entity Model 的方式可以省下開發與修改DAL的時間,非常適合應用在小型或原本沒有DAL的應用程式所取用,這個方式稱為直接對應模型(Direct Mapping Model)但若原本就有 DAL,這樣是否會花太多時間,這個是需要評估的。

整合實例 B:改寫 BLL(商業邏輯層),以存取來自 DAL 的資料物件。

若以改寫 BLL 程式碼的方式來套用 Entity Framework,則可以利用 LINQ to DataSet 來實作:

DataTable table = ProductInfo.GetProductList(categoryID);
var query = from p in table.AsEnumerate()
where p.CategoryID == categoryID
select p;
// output product list to List<T> collection.
List<ProductInfo> productList = query.ToList();
// access objects.
foreach (ProductInfo product in productList)
productList.Add(product.Field<string>(“ProductID”),
product.Field<string>( “Caption”), …);

改寫 BLL 的方式對於重構 BLL 有正面效果,也可以省去改寫 DAL 的時間,對於現有應用程式的整合有較正面且快速的幫助,而且只要關注 DAL 回傳的資料物件,不必煩惱要存取何種類型的資料。

整合實例 C:利用自訂的 Mapping 方式來產生 Entity

像是 Entity Framework 可以利用 CSDL 來建構物件模型;用 SSDL 對應實體儲存;並用 MSL 來結合兩者,這代表可以在 CSDL 固定的情況下,改寫 SSDL 對應方法來改變實體儲存的位置(例如 SQL Server, Access, MySQL, Oracle 等),或者是對應可能原始儲存和物件模型完全不同的結構時,透過 MSL 就可以結合 CSDL 與 SSDL,讓應用程式可以順利的讀取到資料。

這種方式稱為彈性對應(Flexible Mapping),彈性對應的模式可以讓物件模型和儲存模型得以切開,並且只要透過 MSL 就可以將兩者整合,這樣的設計方法可降低程式碼與資料的藕合性,而且應用程式又可以透過像 Object Service 或 LINQ to Entities 等方式來撰寫資料存取程式碼,不必在意儲存端要如何改變,即可有效的分離資料和邏輯兩部份(資料多為 DBA 的工作)。

例如,應用程式有一個物件模型,宣告為 CSDL 如下所示:

<EntityContainer Name="ModelContainer" >
<EntitySet Name="ProductInfoSet" EntityType="DataModel.ProductInfo" />
</EntityContainer>
<EntityType Name="ProductInfo" >
<Key >
<PropertyRef Name="ProductID" />
</Key>
<Property Name="ProductID" Type="Guid" Nullable="false" />
<Property Name="Caption" Type="String" Nullable="true"
MaxLength="2147483647" Unicode="true" FixedLength="false" />
<Property Name="Description" Type="String" Nullable="true"
MaxLength="2147483647" Unicode="true" FixedLength="false" />
</EntityType>

開發人員可以寫這樣的 Storage Schema,以將資料儲存在資料表中:

<EntityType Name="ProductInfoType">
<Property Name="ProductID" Type="String" Nullable="false" />
<Property Name="Name" Type="String" Nullable="false" />
</EntityType>
<EntityContainer Name="TargetContainer">
<EntitySet Name="ProductInfoQuery" EntityType="ProductInfoType" />
</EntityContainer>

或者,若你想要以 SQL 查詢結果做為資料對應的來源,可以改成這樣:

<EntityContainer Name="TargetContainer">
<EntitySet Name="ProductInfoQuery" EntityType="DirectQueryTable">
<DefiningQuery>
SELECT ProductID, Name FROM Products
</DefiningQuery>
</EntitySet>
</EntityContainer>

如此,就算資料來源或結構不同,程式端的物件模型也不會改變,一樣可以保持原程式不變動。

結語

筆者在本篇系列文章中,說明了 ADO.NET Entity Framework 的發展方法以及技術,以及整合的考量與方法,由於 ADO.NET Entity Framework 仍處於 Beta 2 狀態,未來若有更新功能的變動,筆者會以專文來介紹,希望讀者能夠在這個系列文章中獲得想要知道的資訊,若有問題,也可以在 MSDN 論壇的 ADO.NET and LINQ 討論區發問,預祝大家學習順利。

 
 
 

ADO.NET Entity Framework 概觀

作者:朱明中

ADO.NET 回顧

自從微軟在 COM 上推出 ADO(ActiveX Data Object)以後,大大改變了在微軟平台上存取資料庫的方法,而且 ADO 是一個語法上很有彈性的資料存取元件,開發人員可以用 Command 執行 SQL 指令或產生資料結果集,或者直接用 Recordset 來產生結果集,當時以 VB 與 ASP 為主的開發人員,無不大力捧場,使得 ADO 變成當時 ASP 和 VB 程式開發連結資料庫的首選。不過因為 ADO 是一個連結導向(Connection-Oriented)的資料存取物件,會鎖定住資料庫的游標以及連線資源,對於資料庫連線來說,耗損的速度會變的很快,尤其資料庫連線是很貴的(一個 CAL 大約 2,500 元,一百個就要 25 萬了),所以 ADO 在 .NET Framework 中重新設計,導入了離線資料存取模型(Disconnected Data Access),也就是常聽到的 DataSet 與 DataTable,將連線、存取與結果集處理確實分開,組成現在的 ADO.NET 資料存取模型。

功能 ADO ADO.NET
連線 ADODB.Connection 配合所屬的 OLE DB Provider,或者由 OLE DB Provider for ODBC 加上資料庫的 ODBC Driver。 IDbConnection 其衍生類別有 SqlConnection, OleDbConnection, OdbcConnection 與 OracleConnection 等。
指令操作 ADODB.Command IDbCommand
結果集處理 ADODB.Recordset 連線導向。 IDbDataReader: 連線單向型游標。
IDbDataAdapter: 填充資料。
DataSet: 離線型DataTable的集合。

ADO.NET 由 IDbConnection, IDbCommand, IDbDataReader 與 IDbDataAdapter,以及 DataSet/DataTable 等離線資料物件所組成,主要的資料操作都是在 DataSet 和 DataTable 中,而與資料庫連線則是用 IDbConnection,SQL 指令處理在 IDbCommand,另外若想要快速的存取資料,則可以利用 IDbDataReader 所提供的單向游標資料流來存取資料庫。ADO.NET 其實是個相當不錯的資料存取模型,只是因為在 .NET Framework 剛推出時,ADO 轉換到 ADO.NET 在操作習慣上的差異,使得還是有不少人使用 ADO,不過在 .NET 2.0 之後,這個比例已經減少很多了。

不過,就算是 ADO.NET 這樣的模型,也還是會有一個永遠解決不了的問題:SQL 指令。沒錯,要能夠將 ADO.NET 功能發揮到極致的話,就必須要直接處理 SQL 指令,包括 CRUD(Create, Retrieve, Update, Delete)與參數化處理,若資料庫中有檢視表或是預存程序的話,也都要處理到,因而讓程式開發人員多一項 SQL 指令學習的負擔(在台灣的話可算稀鬆平常),為了要解決這樣的問題,於是出現了 Hibernate 技術,這個技術可以套用在 Java 與 .NET中(.NET 的稱為 NHibernate),它利用了資料庫與程式物件間的 Object-Relationship Mapping(O/R Mapping)方式,簡化程式開發人員在處理資料庫物件時的工作。

ADO.NET 的下一個版本:ADO.NET “vNext”就是要實作出一個可以隔離程式碼與資料庫介面的共用 API 層次,讓程式開發人員可以用程式碼的方式存取資料庫,而不是經由 ADO.NET 物件,這個功能在 Entity Framework 被實現出來,再搭配 Language-in-Query(LINQ)能力,讓 .NET Framework 3.5 的資料存取功能又邁入了新的里程碑。

ADO.NET Entity Framework 概觀

ADO.NET Entity Framework 是新一代,具有隔離程式碼與資料庫間,並透過一個新的 API 來存取資料庫的資料存取元件,並且和 LINQ 搭配,讓開發人員不必再撰寫 SQL 指令與 ADO.NET 物件,即可存取資料庫。

為了要達成資料庫與程式碼隔離的能力,必須要有一些中介資料(Meta data)描述資料與物件間的對應,以及設定物件間的關聯(Object Relationship),在 ADO.NET Entity Framework,由三層中介資料(XML)來負責這個工作:

Conceptual Schema

Conceptual Schema 由 CSDL(Conceptual Schema Definition Language)所組成,在設計資料類別時就可以開始定義,以 OOP 的術語來看,每一個類別構成一個 Entity,在 Entity 中會有資料屬性與關聯設定(Association),例如:

<?xml version="1.0" encoding="utf-8"?>
<Schema xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration"
xmlns:edm="http://schemas.microsoft.com/ado/2006/04/edm"
xmlns="http://schemas.microsoft.com/ado/2006/04/edm"
Namespace="NorthwindLib" Alias="Self">
<EntityType Name="Product">
<Key>
<PropertyRef Name="ProductID" />
</Key>
<Property Name="ProductID" Type="Int32" Nullable="false"/>
<Property Name="ProductName" Type="String"
        Nullable="false" MaxLength="40" ConcurrencyMode="fixed" />
<Property Name="UnitPrice" Type="Decimal"
        Nullable="true" Precision="10" Scale="4" ConcurrencyMode="fixed" />
<NavigationProperty Name="Category"
        Relationship="Self.Category_Product"
        FromRole="Product" ToRole="Category" />
</EntityType>
<Association Name="Category_Product">
<End Role="Category" Type="Self.Category"
        Multiplicity="1" />
<End Role="Product" Type="Self.Product"
        Multiplicity="0..*" PluralRole="Products" />
</Association>
<EntityContainer Name="Northwind">
<EntitySet Name="Categories" EntityType="Self.Category" />
<EntitySet Name="Products" EntityType="Self.Product" />
<AssociationSet Name="CategoryProducts" Association="Self.Category_Product">
<End Role="Category" EntitySet="Categories" />
<End Role="Product" EntitySet="Products" />
</AssociationSet>
</EntityContainer>
</Schema>

在 Entity 中會定義 Entity 的主鍵(Primary Key)、每個屬性的資料型別、可否 NULL 以及其他的資訊(例如可容納字串大小)等,這些資訊會影響到未來存取 Entity 時的指令。每個 Conceptual Schema 中可能包含很多的 Entity 以及 Association 所組成,所以要管理這些 Entity,就需要有一個集合來處理,這個集合就是 EntityContainer,不但可以包含多個 Entity,也可以引入其他的 Entity。

<?xml version="1.0" encoding="utf-8"?>
<Schema xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration"
xmlns:edm="http://schemas.microsoft.com/ado/2006/04/edm"
xmlns="http://schemas.microsoft.com/ado/2006/04/edm"
Namespace="MyCompany.ContainerType">
<EntityContainer name="ContainerOne">
<Using Namespace="MyCompany.EntityTypes" Alias="basicTypes"/>
<Using Namespace="MyCompany.RelationshipTypes" Alias="relnTypes"/>
<EntitySet Name="CustomerSet" EntityType="basicTypes.Customer"/>
<EntitySet Name="OrderSet" EntityType="basicTypes.Order"/>
<AssociationSet Name="CustomerOrderSet"
      Association="relnTypes.CustomerOrder">
<End EntitySet="CustomerSet" Role="Orders"/>
<End EntitySet="OrderSet" Role="OrderedBy"/>
</AssociationSet>
</EntityContainer>
</Schema>

除了 Entity 外,每個 Entity 間可能會有一些關聯性,這個關聯可能是一對一或一對多等,這些關聯稱為 Association,並且會依多元程度(Degree)、對應實體數(Multiplicity)與方向(Direction)識別。

例如以下的 Schema 就定義了 Product 與 Category 兩個 Entity 的關聯:


圖:一元關係。


圖:二元關係。


圖:三元關係。

<Association Name="Category_Product">
<End Role="Category" Type="Self.Category"
        Multiplicity="1" />
<End Role="Product" Type="Self.Product"
        Multiplicity="0..*" PluralRole="Products" />
</Association>

Storage Schema

在實體資料庫的部份,是由 Storage Schema 負責,定義了資料庫的各種物件,如資料表、預存程序、使用者定義函數與檢視表等等。

<?xml version="1.0" encoding="utf-8"?>
<Schema Namespace="AdventureWorksHRTarget" Alias="Self"
xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
<EntityType Name="Department">
<Key>
<PropertyRef Name="DepartmentID">
</Key>
<Property Name="DepartmentID" Type="smallint"
Nullable="false" StoreGeneratedPattern="identity" />
<Property Name="Name" Type="nvarchar"
Nullable="false" MaxLength="50" />
<Property Name="GroupName" Type="nvarchar"
Nullable="false" MaxLength="50" />
<Property Name="ModifiedDate" Type="datetime" Nullable="false" />
</EntityType>
<EntityType Name="Employee" >
<Key>
<PropertyRef Name="EmployeeID">
</Key>
<Property Name="EmployeeID" Type="int" Nullable="false"
StoreGeneratedPattern="identity" />
<Property Name="NationalIDNumber" Type="nvarchar"
Nullable="false" MaxLength="15" />
<Property Name="ContactID" Type="int" Nullable="false" />
<Property Name="LoginID" Type="nvarchar"
Nullable="false" MaxLength="256" />
<Property Name="ManagerID" Type="int" />
<Property Name="Title" Type="nvarchar" Nullable="false"
MaxLength="50" />
<Property Name="BirthDate" Type="datetime" Nullable="false" />
<Property Name="MaritalStatus" Type="nchar" Nullable="false"
MaxLength="1" FixedLength="true" />
<Property Name="Gender" Type="nchar" Nullable="false"
MaxLength="1" FixedLength="true" />
<Property Name="HireDate" Type="datetime" Nullable="false" />
<Property Name="SalariedFlag" Type="bit" Nullable="false" />
<Property Name="VacationHours" Type="smallint" Nullable="false" />
<Property Name="SickLeaveHours" Type="smallint" Nullable="false" />
<Property Name="CurrentFlag" Type="bit" Nullable="false" />
<Property Name="rowguid" Type="uniqueidentifier" Nullable="false" />
<Property Name="ModifiedDate" Type="datetime" Nullable="false" />
</EntityType>
<EntityContainer Name="HumanResources">
<EntitySet Name="Department" EntityType="Self.Department" />
<EntitySet Name="Employee" EntityType="Self.Employee" />
<AssociationSet Name="Employee_EmployeeManagerID"
Association="Self.Employee_EmployeeManagerID">
<End Role="Employee" EntitySet="Employee" />
<End Role="Employee" EntitySet="Employee" />
</AssociationSet>
</EntityContainer>
</Schema>

基本上和 Conceptual Schema 差異不大,但因為要對應到實體資料庫,所以所用的設定都要和實體資料庫相同,否則會有對應上的錯誤。

Mapping Schema

當 Conceptual Schema 與 Storage Schema 定義完成後,再把它們串在一起,就完成了整個 Entity Model 的定義,而負責將 Conceptual 與 Storage Schema 串起來的工作,就由 Mapping Schema(由 MSL 組成)來處理。

<?xml version="1.0" encoding="utf-8"?>
<Mapping xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS"
xmlns:edm="urn:schemas-microsoft-com:windows:storage:mapping:CS"
Space="C-S">
<EntityContainerMapping
    CdmEntityContainer="Northwind" StorageEntityContainer="dbo">
<EntitySetMapping Name="Categories">
<EntityTypeMapping TypeName="NorthwindLib.Category">
<MappingFragment StoreEntitySet="Categories">
<ScalarProperty Name="CategoryID" ColumnName="CategoryID" />
<ScalarProperty Name="CategoryName" ColumnName="CategoryName" />
<ScalarProperty Name="Description" ColumnName="Description" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="Products">
<EntityTypeMapping TypeName="NorthwindLib.Product">
<MappingFragment StoreEntitySet="Products">
<ScalarProperty Name="ProductID" ColumnName="ProductID" />
<ScalarProperty Name="ProductName" ColumnName="ProductName" />
<!--<ScalarProperty edm:Name="CategoryID"
edm:ColumnName="CategoryID" />-->
<ScalarProperty Name="UnitPrice" ColumnName="UnitPrice" />
<Condition ColumnName="Discontinued" Value="false" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="NorthwindLib.DiscontinuedProduct">
<MappingFragment StoreEntitySet="Products">
<ScalarProperty Name="ProductID" ColumnName="ProductID" />
<ScalarProperty Name="ProductName" ColumnName="ProductName" />
<!--<ScalarProperty edm:Name="CategoryID"
edm:ColumnName="CategoryID" />-->
<ScalarProperty Name="UnitPrice" ColumnName="UnitPrice" />
<ScalarProperty Name="UnitsInStock" ColumnName="UnitsInStock" />
<Condition ColumnName="Discontinued" Value="true" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<AssociationSetMapping Name="CategoryProducts"
                TypeName="NorthwindLib.Category_Product"
                StoreEntitySet="Products">
<EndProperty Name="Category">
<ScalarProperty Name="CategoryID" ColumnName="CategoryID" />
</EndProperty>
<EndProperty Name="Product">
<ScalarProperty Name="ProductID" ColumnName="ProductID" />
</EndProperty>
</AssociationSetMapping>
</EntityContainerMapping>
</Mapping>

存取 ADO.NET Entity Framework

在定義好每個 Schema 後,就可以利用 Entity Framework 所提供的 API,或者是透過 LINQ to Entities 來存取 Entity。

存取介面 說明
LINQ to Entities 直接透過 LINQ 存取,可完全將程式碼與資料庫間完全隔離,並且由 LINQ 自動使用內部的介面(即 Object Service)來存取資料庫。
Object Service 可以透過 Entity SQL 來存取 Entity,並且直接以物件的方式來存取結果集(因為結果集本身就是物件的集合)。
EntityClient 透過類似 ADO.NET 的方法,以及 Entity SQL 存取 Entity。

若是用 LINQ to Entities 來存取,則開發人員可完全不必處理任何SQL指令(除了 LINQ 的語法以外),即可存取資料庫中的資料,而這些資料都以物件方式呈現:

using (AdventureWorksEntities AWEntities = new AdventureWorksEntities())
{
ObjectQuery<Product> products = AWEntities.Product;
IQueryable<string> productNames =
from p in products
select p.Name;
Console.WriteLine("Product Names:");
foreach (var productName in productNames)
{
Console.WriteLine(productName);
}
}

若是用 Object Service,則會用到一些 SQL(Entity SQL):

using (AdventureWorksEntities advWorksContext =
new AdventureWorksEntities())
{
try
{
string queryString =
@"SELECT VALUE Product FROM AdventureWorksEntities.Product AS Product";
ObjectQuery<Product> productQuery =
new ObjectQuery<Product>(queryString, advWorksContext, MergeOption.NoTracking);
// Iterate through the collection of Product items.
foreach (Product result in productQuery)
Console.WriteLine("Product Name: {0}; Product ID: {1}",
result.Name, result.ProductID);
}
catch (QueryException ex)
{
Console.WriteLine(ex.ToString());
}
}

若是想要用類似 ADO.NET 的方式來存取 Entity 的話,則可以利用 Entity Client 來實作:

static void Main(string[] args)
{
String connString =
@"Provider=System.Data.SqlClient;
Metadata=.;
Provider Connection String='Server=.;
Database=AdventureWorks;
            Integrated Security=true;
Connection Timeout=5;
MultipleActiveResultSets=true;'";
String esqlQuery = @"SELECT VALUE p.ProductID
FROM AdventureWorksEntities.Product AS p";
try
{
using (EntityConnection conn =
new EntityConnection(connString))
{
// Open a connection.
conn.Open();
EntityCommand cmd = conn.CreateCommand();
cmd.CommandText = esqlQuery;
// Execute the query.
using (EntityDataReader rdr = cmd.ExecuteReader
(CommandBehavior.SequentialAccess))
{
// Start reading records.
PrintReader(rdr);
}
}
}
catch (System.Data.MappingException e)
{
Console.WriteLine(e.ToString());
}
catch (System.Data.CommandExecutionException e)
{
Console.WriteLine(e.ToString());
}
}
}

Visual Studio 的支援

在 Visual Studio 2008 中,ADO.NET Entity Framework 提供了圖形化介面的工具:Entity Data Model Wizard,可以自動連接資料庫,產生相對應的 C/S(Conceptual/Storage)與 MSL 等定義,開發人員可以省下很多工夫。另外也提供了一個命令列工具:edmgen.exe,可以讓開發人員產生或檢驗 C/S 與 MSL 等設定格式是否正確。

結語

ADO.NET Entity Framework 將 ADO.NET 的資料存取能力抽象化,讓開發人員可以在不必關注資料庫的情況下,以程式語言提供的方法來存取資料庫,將資料庫管理與存取的工作交由資料庫的專家來處理,無形中可簡化許多在資料存取工作上消耗的時間,未來我們會再進一步討論這個新功能。

參考資料

ADO.NET Entity Framework Beta 2: http://www.microsoft.com/downloads/details.aspx?FamilyID=f1adc5d1-a42e-40a6-a68c-a42ee11186f7&DisplayLang=en

ADO.NET Entity Framework Tools Preview: http://www.microsoft.com/downloads/details.aspx?familyid=09A36081-5ED1-4648-B995-6239D0B77CB5&displaylang=en

 
下面这篇文章来自msnd,在index中输入 Entity Framework即可找到:
.NET Framework 开发人员指南
ADO.NET 路线图
请参见  发送反馈意见

 

多数业务应用程序都会与数据进行交互,这些数据通常存储在关系数据库中。 关系数据依赖于针对数据存储和完整性,而不是针对应用程序开发进行优化的规范化数据库架构。 应用程序通常会使用比关系架构的平面行和列更丰富的数据模型。 另外,有关数据库的知识必须在应用程序内进行硬编码,这可能会使应用程序在基础架构改变时中断。

企业级应用程序通常通过隔离到独立的应用程序层而与数据库引擎解除耦合。 数据访问逻辑局限于数据抽象层 (DAL)。 不过,创建和维护稳定而灵活的 DAL 可能会不相称地消耗过多份额的应用程序开发和维护成本。

通过使应用程序开发人员能够对可灵活映射到存储架构的概念实体数据模型进行编码,ADO.NET Entity Framework 解决了这些问题。

“折叠”图像实体数据模型

数据建模的一种常见设计模式是将数据模型分为三部分:

  • 概念模型,该模型定义要建模的系统中的实体和关系。 概念模型通常用于在项目的早期阶段捕获应用程序要求,随着项目的进展,通常会被丢弃。

  • 逻辑模型,该模型会通过外键约束将实体和关系规范化到数据库表中。 许多开发团队会跳过概念模型的创建,一开始就通过定义数据库中的表、列和键来使用逻辑模型。 然后,应用程序的程序员通过编写 SQL 查询和调用存储过程来编写面向逻辑模型的代码。

  • 物理模型,该模型指定引擎特定的存储详细信息,例如分区和索引。 物理模型由负责安全性、数据完整性、维护和性能优化的数据库管理员来维护。

ADO.NET Entity Framework 使开发人员能够编写对从 Entity Data Model (EDM) 生成的对象而不直接对逻辑(关系)模型执行操作的代码,从而扩展了概念模型的功能。 然后,Entity Framework 会将这些操作映射到存储特定的关系命令。

Entity Framework 应用程序提供以下好处:

  • 应用程序不再对特定的数据引擎或逻辑模型具有硬编码依赖性。

  • 可以更改概念模型和存储特定逻辑模型之间的映射而不更改应用程序代码。

  • 开发人员可以使用可映射到各种存储架构(可能在不同的数据库管理系统中实现)的一致的应用程序对象模型。

  • 多个应用程序模型可以映射到同一个存储架构。

  • 语言集成查询支持可为查询提供针对概念模型的编译时语法验证。

  • 数据模型具有诸如带类型层次结构的强类型、可导航的关系和复杂类型等功能,其表达性比传统关系数据库更丰富。

“折叠”图像实体数据平台

Microsoft 将其实体数据平台预想成一种多版本策略,通过使开发人员能够针对概念性实体数据模型编程,减少代码量和所需的维护。 第一个版本在 Visual Studio 的 Visual Studio 2008 版本和 .NET Framework 中推出。

LINQ

Visual Studio 的 Visual Studio 2008 版本和 .NET Framework 中引入了语言集成查询功能 (LINQ),该功能将一组通用的标准查询运算符集成到了 Visual C# 和 Visual Basic 的语言语法中。 LINQ 引入了标准易学的数据查询和更新模式,并可以扩展以支持可能的任何数据类型。 有关更多信息,请参见Getting Started with LINQ

Visual Studio 的 Visual Studio 2008 版本和 .NET Framework 包括 LINQ 的以下实现:

LINQ to DataSet

为数据集中存储的已断开连接的数据提供语言集成查询功能。 有关更多信息,请参见 LINQ to DataSet 概述

LINQ to XML

提供文档对象模型 (DOM) 的内存中文档修改功能,并支持 LINQ 查询表达式。 有关更多信息,请参见 LINQ to XML 概述

LINQ to Objects

提供 LINQ 查询以访问内存中的数据结构,例如列表、数组、字典和集合。 有关更多信息,请参见 LINQ to Objects

LINQ to SQL

通过将关系数据模型映射到用开发人员的编程语言表示的对象模型,启用对 Microsoft SQL Server 数据库的 LINQ 查询。 有关更多信息,请参见 LINQ to SQL

Entity Framework

Microsoft 将在推出 Visual Studio 2008 后发布 ADO.NET Entity Framework 作为 .NET Framework 的扩展。

Entity Framework 发布将包括下列组件:

术语

定义

Entity Data Model (EDM)

指定用于生成由应用程序代码使用的可编程类的概念架构。 用于保持数据的存储结构在存储架构中表示,概念架构和存储架构之间由映射规范连接。 Entity Framework 使用 EDM 来定义概念实体,这些概念实体可以使用数据读取器以序列化形式读取,也可以具体化为对象。 开发人员可以根据需要扩展这些对象,以支持不同的应用程序需要。

Entity SQL

定义一种基于 SQL 的公共查询语言,该语言经过扩展,可以按照 EDM 概念(如类型和可导航关系)在不同数据库之间表示查询。 EntityClientObject Services 都支持 Entity SQL。

EntityClient

一个 ADO.NET 数据提供程序,按照概念性实体数据模型公开数据,可通过公共 Entity SQL 语言进行查询,能够灵活映射到存储特定的数据提供程序。

Object Services

允许程序员通过一组公共语言运行库 (CLR) 类与概念模型交互。 这些类可以从概念模型自动生成,也可以单独开发以反映概念模型的结构。 Object Services 还为 Entity Framework 提供基础结构支持,提供诸如状态管理、更改跟踪、标识解析、加载和浏览关系、将对象更改传播到数据库修改和 Entity SQL 查询生成支持等服务。

LINQ to Entities

为查询实体提供语言集成查询 (LINQ) 支持。

“折叠”图像LINQ 和关系数据

LINQ to SQL 和 LINQ to Entities 是用于处理数据的两种不同方法。

LINQ to SQL 支持快速应用程序开发,通过将对象直接映射到 SQL Server 表、视图、存储过程和表值函数来查询 Microsoft SQL Server 数据库。 LINQ to SQL 将作为 Visual Studio 2008 和 .NET Framework 的一部分提供。

LINQ to Entities 支持对 Entity Data Model 进行查询。 LINQ to Entities 将作为 ADO.NET Entity Framework 的一部分在 Visual Studio 2008 和 .NET Framework 的更新中提供。

如果您编写的应用程序需要以下任一功能,则应考虑使用 LINQ to Entities 和 ADO.NET Entity Framework:

  • 定义到现有关系架构的灵活映射的能力,例如:

    • 将单个类映射到多个表。

    • 映射到不同的继承类型。

    • 直接建模多对多关系。

    • 公开属性组作为单一复合(复杂)类型。

    • 映射到对数据库的任意查询。

  • 查询 Microsoft SQL Server 系列产品以外的关系数据库的能力。

  • 跨多个应用程序或服务共享模型的能力。

  • 基于字符串的查询语言。

  • 查询概念模型而不将结果具体化为对象的能力。

如果您不需要这些功能,LINQ to SQL 还可为应用程序提供更简单的方法,使数据类直接映射到您的 Microsoft SQL Server 数据库。

当需要更灵活的映射或需要访问 Microsoft SQL Server 以外的数据库时,Microsoft 将提供相应的工具和指南以帮助客户开始使用 LINQ to SQL 将其应用程序迁移到 LINQ to Entities。

Entity Framework 将在经过公开测试和技术预览后面世。

“折叠”图像请参见

 

Category : .NetC#Window$WPF其他

Tags :

发表评论

电子邮件地址不会被公开。

Proudly powered by WordPress and Sweet Tech Theme