Entity Framework 又稱 ADONET Entity Framework 是微軟以 ADONET 為基礎所發展出來的物件關聯對應 OR Mapping 解決方案，早期被稱為 ObjectSpace，包含在 NET Framework 中發表。從版本 6 開始獨立釋出。 背景 長久以來，程式設計師和資料庫總是保持著一種微妙的關係，在商用應用程式中，資料庫一定是不可或缺的元件，這讓程式設計師一定要為了連線與存取資料庫而去學習 SQL 指令，因此在資訊業中有很多人都在研究如何將程式設計模型和資料庫整合在一起，物件關聯對應 ObjectRelational Mapping 的技術就是由此而生，像 Hibernate 或 NHibernate 都是這個技術下的產物，而微軟雖然有了 ADONET 這個資料存取的利器，但卻沒有像 NHibernate 這樣的物件對應工具，因此微軟在NET Framework 20 發展時期，就提出了一個 ObjectSpace 的概念，ObjectSpace 可以讓應用程式可以用完全物件化的方法連線與存取資料庫，其技術概念與 NHibernate 相當類似，然而 ObjectSpace 工程相當大，在NET Framework 20 完成時仍無法全部完成，因此微軟將 ObjectSpace 納入下一版本的NET Framework 中，並且再加上一個設計的工具（Designer），構成了現在的 ADONET Entity Framework。 Entity Framework 是 ADONET 之上支援面向資料應用程式開發，使得開發者工作於領域相關的物件和屬性的資料級，如客戶、客戶地址等，不必關注儲存資料的底層表、列。這種在更高層次上建立、維護面向資料的應用程式可以大大節約編碼量。 Entity Framework 利用了抽象化資料結構的方式，將每個資料庫物件都轉換成應用程式物件 entity，而資料欄位都轉換為屬性 property，關聯則轉換為結合屬性 association，讓資料庫的 ER 模型完全的轉成物件模型，如此讓程式設計師能用最熟悉的程式語言來呼叫存取。而在抽象化的結構之下，則是高度整合與對應結構的概念層、對應層和儲存層，以及支援 Entity Framework 的資料提供者 provider，讓資料存取的工作得以順利與完整的進行。 概念層：負責向上的物件與屬性顯露與存取。 對應層：將上方的概念層和底下的儲存層的資料結構對應在一起。 儲存層：依不同資料庫與資料結構，而顯露出實體的資料結構體，和 Provider 一起，負責實際對資料庫的存取和 SQL 的產生。 歷史 2008 年 8 月 11 日，Entity Framework 的第一版 EFv1 隨NET Framework 35 Service Pack 1 和 Visual Studio 2008 Service Pack 1 釋出。該版受到了廣泛的批評。 2010 年 4 月 12 日，Entity Framework 第 2 版，稱為 Entity Framework 40 EFv4 釋出，解決了第一版的很多問題。該版本完全包含在NET Framework 中。 2011 年 4 月 12 日釋出了 Entity Framework 第 3 個版本，稱為 version 41，開始支援 Code First。2011 年 7 月 25 日釋出了 Entity Framework 41 Update 1。 2012 年 2 月 29 日釋出了 version 431。 2012 年 8 月 11 日釋出了 Version 500。與NET framework 45 配套。 2013 年 10 月 17 日釋出了 Version 60。併成為開源軟體，使用 Apache License v2 類似於 ASPNET MVC，開源釋出於 GitHub。 This version has a number of improvements for codefirst supportEntity Framework 60、61、62、63 和 64 完全作為 NuGet 包提供。 2014 年 5 月 19 日，微軟決定為了讓其NET 能跨平臺，下一版 Entity Framework 將完全重寫。2016 年 6 月 27 日，釋出了 Entity Framework Core 10 伴隨著 ASPNET Core 10 和 NET Core 10 本來其命名為 Entity Framework 7，但為了突出其是完全重寫而不是替換 EF6 所以重新命名。 架構 ADONET Entity Framework 架構，從底向上包括： Data source specific providers ADONET 抽象介面連線到資料庫。 Map provider 特定資料庫的 provider，翻譯 Entity SQL 命令樹到資料庫本地 SQL 方言查詢。包括 Storespecific bridge，負責把一般命令樹翻譯為儲存特定的命令樹。 EDM parser and view mapping 把資料模型的特定的 SDL 規範和如何對映到關係模型。從關係模式角度，它建立了對應於概念模型的資料 views。它聚合（aggregate）多張表的資訊成為一個實體（entity），把一個到實體的修改（update）分割為到多個表的修改。 Query and update pipeline 處理查詢、過濾器、修改等請求，轉化為經典命令樹。 Metadata services 處理實體、關係、對映的所有元資料。 Transactions 整合基礎儲存的事務能力。如果基礎儲存不支援事務，則在這個層次上實現事務。 Conceptual layer API 提供了概念模式下的程式設計介面。遵從 ADONET 模式，使用 Connection 物件引用 map provider 使用 Command 物件傳送查詢，返回 EntityResultSets 或 EntitySets 以包含結果。 Disconnected components ADONET Entity Framework 使用的本地快取資料集和實體集，在偶爾連線環境。 Embedded database ADONET Entity Framework 包含一個輕量嵌入資料庫用於客戶端快取和查詢關係資料庫。 Design tools 如 Mapping Designer ADONET Entity Framework 包含的用於簡化對映從概念模式到關係模式，指出實體型別的哪些屬性對映到資料庫的哪個表。 Programming layer 暴露 EDM 作為程式設計結構，可被程式語言使用 Object services 自動產生 CLR 類程式碼，把同一屬性作為一個實體，允許實體例項作為NET 物件 Web services 暴露 web 服務的實體 Highlevel services 如工作在實體上的報告服務。 概念層結構 概念層結構定義了物件模型 Object Model，讓上層的應用程式碼可以如物件導向的方式般存取資料，概念層結構是由 CSDL Conceptual Schema Definition Language 所撰寫。 一份概念層結構定義如下所示： xml version10 encodingutf8 Schema NamespaceEmployees AliasSelf xmlnshttpschemasmicrosoftcomado200604edm EntityContainer NameEmployeesContext EntitySet NameEmployees EntityTypeEmployeesEmployees EntityContainer EntityType NameEmployees Key PropertyRef NameEmployeeId Key Property NameEmployeeId TypeGuid Nullablefalse Property NameLastName TypeString Nullablefalse Property NameFirstName TypeString Nullablefalse Property NameEmail TypeString Nullablefalse EntityType Schema 對應層結構 對應層結構負責將上層的概念層結構以及下層的儲存體結構中的成員結合在一起，以確認資料的來源與流向。對應層結構是由 MSL Mapping Specification Language 所撰寫。 一份對應層結構定義如下所示： xml version10 encodingutf8 Mapping SpaceCS xmlnsurnschemasmicrosoftcomwindowsstoragemappingCS EntityContainerMapping StorageEntityContainerdbo CdmEntityContainerEmployeesContext EntitySetMapping NameEmployees StoreEntitySetEmployees TypeNameEmployeesEmployees ScalarProperty NameEmployeeId ColumnNameEmployeeId ScalarProperty NameLastName ColumnNameLastName ScalarProperty NameFirstName ColumnNameFirstName ScalarProperty NameEmail ColumnNameEmail EntitySetMapping EntityContainerMapping Mapping 儲存層結構 儲存層結構是負責與資料庫管理系統（DBMS）中的資料表做實體對應 Physical Mapping，讓資料可以輸入正確的資料來源中，或者由正確的資料來源取出。它是由 SSDL Storage Schema Definition Language 所撰寫。 一份儲存層結構定義如下所示： xml version10 encodingutf8 Schema NamespaceEmployeesStore AliasSelf ProviderSystemDataSqlClient ProviderManifestToken2005 xmlnshttpschemasmicrosoftcomado200604edmssdl EntityContainer Namedbo EntitySet NameEmployees EntityTypeEmployeesStoreEmployees EntityContainer EntityType NameEmployees Key PropertyRef NameEmployeeId Key Property NameEmployeeId Typeuniqueidentifier Nullablefalse Property NameLastName Typenvarchar Nullablefalse MaxLength50 Property NameFirstName Typenvarchar Nullablefalse Property NameEmail Typenvarchar Nullablefalse EntityType Schema Entity Data Model Entity Data Model EDM 給出資料的概念模型 CSDL ，這所使用的建模技術被稱為 Entity Data Model 是實體 關係模型的擴充套件版。資料模型主要描述了實體和其涉及的關聯（Association）。EDM 模式用 Schema Definition Language SDL 表述，這事 XML 的一種應用。此外，從概念模式 CSDL 到儲存模式 SSDL 的對映 MSL 也必須用 XML 表示。 Visual Studio 提供了 Entity Designer 視覺化建立 EDM 和對映規範。該工具輸出 XML 檔案 edmx 來描述這種模式和對映。Edmx 檔案包含 EF 元資料 CSDLMSLSSDL 內容。也可手工編輯這 3 個檔案 csdl msl ssdl。 Mapping Visual Studio 的 Entity Data Model Wizard 在大部分情況下最初產生資料庫模式和概念模式的 1 對 1 對映。關係模式下，表和主鍵、外部索引鍵組成元素。實體型別 定義了概念模式下的資料。 實體型別是多個型別欄位的聚合，每個欄位對映到資料庫的特定列，可以包含來自多個物理表的資訊。實體型別可以彼此有關係，且獨立於物理模式內的關係。相關的實體可以透過欄位的名字表示這種關係，以代替從資料庫的列獲取值，透過這種欄位可以遍歷相關的實體，返回一個實體或實體集合。 實體型別形成了物件的類，實體是整個型別的例項。實體是應用程式的單個物件，用一個鍵索引。 ADONET Entity Framework 使用 Entity Data Model EDM 表示這種對映。 ADONET Entity Framework 使用 eSQL，SQL 的一個派生，來執行查詢、集合論操作、修改實體及其關係。 實體 實體是 實體型別 的例項，表示單個物件的例項（如 客戶、訂單）。ADONET Entity Framework 中的實體屬性是完全型別化的，完全兼容於 DBMS 的型別系統和NET Framework 的 Common Type System。屬性可以是 SimpleType 或 ComplexType 或多值的。所有 EntityType 屬於某個名稱空間，幷包含一個 EntityKey 屬性。 所有實體例項在 EntityContainers 中。每個專案有一個或多個 EntityContainers。 EDM 基礎型別 簡單型別 EDM 型別 CLR 型別對映 關係 任何兩個實體型別可以是相關的，或者是 Association 關係或者 Containment 關係。用 Relationship Type 來表示。 關係型別用 degree arity 和 multiplicity 刻畫。ADONET Entity Framework 支援二元雙向關係，multiplicity 包括一對一、一對多、多對多。實體間的關係是有名的，稱為 Role。定義了關係的目的。 關係型別可以有 Operation 或 Action。例如，刪除一個實體，其關聯的關係可以採取： Cascade：刪除關係例項和所有相關聯的實體例項。 None 模式定義語言 ADONET Entity Framework 使用基於 XML 的資料定義語言稱為 Schema Definition Language SDL 定義 EDM Schema。SDL 定義了 SimpleTypes 類似於 CTS 基礎型別，包括 String Int32 Double Decimal Guid 和 DateTime 等等。列舉型別定義了基礎值和其名字的對映，也被認為是簡單型別。ComplexTypes 為其他型別的聚合。屬性的集合定義了實體型別。寫為巴恩斯瑙爾正規化： EntityType ENTITYTYPE entityTypeName BASE entityTypeName ABSTRACT truefalse KEY propertyName propertyName propertyName PropertyType PropertyFacet PropertyType PrimitiveType PrimitiveTypeFacets complexTypeName RowType PropertyFacet NULLABLE true false DEFAULT defaultVal MULTIPLICITY 1 PropertyTypeFacet MAXLENGTH PRECISION SCALE UNICODE FIXEDLENGTH COLLATION DATETIMEKIND PRESERVESECONDS PrimitiveType BINARY STRING BOOLEAN SINGLE DOUBLE DECIMAL GUID BYTE SBYTE INT16 INT32 INT64 DATETIME DATETIMEOFFSET TIME Facets 用於描述屬性的元資料，如是否為可空、預設值、為單值或多值。 ComplexType NameAddr Property NameStreet TypeString Nullablefalse Property NameCity TypeString Nullablefalse Property NameCountry TypeString Nullablefalse Property NamePostalCode TypeInt32 ComplexType EntityType NameCustomer Key PropertyRef NameEmail Key Property NameName TypeString Property NameEmail TypeString Nullablefalse Property NameAddress TypeAddr EntityType 關係型別，如客戶和訂單是 1 對多關係。 Association NameCustomerAndOrders End TypeCustomer Multiplicity1 End TypeOrders Multiplicity OnDelete ActionCascade End Association 查詢物件 ADONET 實體資料模型工具會產生從 ObjectContext 代表概念模型中所定義的實體容器 衍生而來的類別。 ObjectContext 類別支援針對將實體當成物件傳回之概念模型進行查詢，也支援建立、更新和刪除實體物件。 Entity Framework 支援針對概念模型進行物件查詢。 這些查詢可以使用 Entity SQL 、LanguageIntegrated Query LINQ 和物件查詢產生器方法來撰寫。 Entity SQL Entity Client 是 ADONET Entity Framework 中的原生使用者端 Native Client。它的物件模型和 ADONET 的其他使用者端非常相似，一樣有 Connection Command DataReader 等物件，但最大的差異就是，它有自己的 SQL 指令 Entity SQL，可以用 SQL 的方式存取 EDM。但沒有明確的 joins。簡單的說，就是把 EDM 當成一個實體資料庫。 查詢管線分析 Entity SQL 查詢為一棵命令樹， query into a command tree 分開多個表上的查詢，再移交 EntityClient provider。EntityClient provider 使用 Connection 物件初始化。EntityClient provider 再把 Entity SQL 命令樹轉化為資料庫的本地 SQL 查詢。查詢返回 Entity SQL ResultSet，但不限於一個表的結果。 Initialize the EntityConnectionStringBuilder EntityConnectionStringBuilder entityBuilder new EntityConnectionStringBuilder Set the provider name entityBuilderProvider providerName Set the providerspecific connection string entityBuilderProviderConnectionString providerString Set the Metadata location entityBuilderMetadata resAdventureWorksModelcsdl resAdventureWorksModelssdl resAdventureWorksModelmsl ConsoleWriteLine entityBuilderToString using EntityConnection conn new EntityConnection entityBuilderToString connOpen ConsoleWriteLine Just testing the connection connClose Entity SQL 經典函式 Entity Framework 相容的 data providers 都支援的函式，可用於 Entity SQL 查詢。LINQ to Entities 的大部門擴充套件方法都翻譯為經典函式。ADONET data provider 會把經典函式翻譯為期望的 SQL 語句。 類別 經典函式 聚類函式 數學函式 字串函式 日期時間函式 Bitwise 函式 其他函式 LINQ to Entities 實作 IEnumerableT 泛型介面或 IQueryableT 泛型介面的資料來源可以透過 LINQ 進行查詢。 實作泛型 IQueryableT 介面之泛型 ObjectQueryT 類別的執行個體會當做 LINQ to Entities 查詢的資料來源。 ObjectQueryT 泛型類別表示傳回零個或多個具型別物件之集合的查詢。 使用 C 的 var 關鍵字 在 Visual Basic 中為 Dim，您也可以讓編譯器推斷實體型別。 using AdventureWorksEntities AWEntities new AdventureWorksEntities ObjectQueryProduct products AWEntitiesProducts LINQ Query syntax IOrderedQueryableProduct query from product in products orderby productName productListPrice descending select product LINQ Method syntax IOrderedQueryableProduct query products OrderBy product productName ThenByDescending product productListPrice 查詢產生器方法 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 ObjectQueryContact contactQuery contextContact Where itLastName ln AND itFirstName fn new ObjectParameter ln lastName new ObjectParameter fn firstName 開發工具 目前 ADONET Entity Framework 的開發，在 Visual Studio 2008 中有充分的支援，在安裝 Visual Studio 2008 Service Pack 1 後，檔案範本中即會出現 ADONET 實體資料模型 ADONET Entity Data Model 可讓開發人員利用 Entity Model Designer 來設計 EDM，EDM 亦可由 Windows 記事本等文字編輯器所編輯。 衍生服務 微軟特別針對了網路上各種不同的應用程式（例如 AJAX，Silverlight，Mashup 應用程式）開發了一個基於 ADONET Entity Framework 之上的服務，稱為 ADONET Data Services（專案代號為 Astoria），並與 ADONET Entity Framework 一起包裝在 NET Framework 35 Service Pack 1 中發表。 支援廠商 目前已有數個資料庫廠商或元件開發商宣佈要支援 ADONET Entity Framework Mircosoft 支援 MsSQL 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 資料庫。 參考資料 外部連結 MSDN Library ADONET Entity Framework 讀寫 ADONET Entity Framework 整合 ADONET Entity Framework 到應用程式中 首次接觸 ADONET Entity Framework ADONET Entity Framework 概觀 Recent ADONET Entity Framework provider news Demos and downloads CategoryNET