ADO.NET
使用 Entity Framework 實現彈性的資料模型
Elisa Flasko
本文討論下列主題:
- Entity Framework 背後的原理
- 實體資料模型 (EDM)
- 查詢、對應及多層式架構 (N-Tier) 的開發
|
本文使用下列技術:
ADO.NET、LINQ、Entity Framework
|

目錄
ADO.NET Entity Framework 就快問世了!這個架構當初在 2006 年是以 ADO.NET vNext 引進,而現在已經備妥要在 Visual Studio® 2008 SP1 中亮相。經過這幾年在類似產品的一連串失敗之後,Microsoft 在 Visual Studio 2008 中發行了兩項技術,它們在某種程度上屬於物件關聯式對應 (Object Relational Mapping,ORM):LINQ to SQL 及 ADO.NET Entity Framework隨著市場開始採用這些技術,開發人員現在想知道過去的來龍去脈,以及 Microsoft 的下一步。他們也想知道開發這些技術的內幕、Entity Framework 與市場上其他 ORM 技術不同之處,以及 Microsoft 未來將如何繼續投資與發展這些技術?
在 Visual Studio 2008 的初版之後,有許多篇文章聚焦於 LINQ to SQL,還有一些文章討論該使用哪一項技術 (請參閱
msdn.microsoft.com/data)。在本文章中,我將把重點放在 Entity Framework,並針對開發期間如何及為何做選擇,提供更深入的探討。
Microsoft® 實體資料模型 (Entity Data Model,EDM) 是以 Dr. Peter Chen 的實體關係 (Entity Relationship,ER) 模型為基礎,是 ADO.NET Entity Framework 背後真正的驅動力。EDM 也是 Entity Framework 與市場上其他 ORM 式技術之間最大差別的特性。EDM 建置在 ER 模型之上,用以提升模型的抽象層,使其優於邏輯模型但同時保留實體與關係的概念。
為何需要另一個資料模型?
那麼,為何需要另一個模型呢?由於公司處理的資料量不斷增加,要了解資料以及在該資料上開發應用程式變得非常困難。資料庫結構描述在設計時有儲存上的考量,例如資料完整性、效能及管理,因此往往不容易了解。通常這些結構描述與應用程式結構也不一致,這使得開發及維護工作更加複雜。
將資料結構與所建置之應用程式分開的自訂解決方案很常見。只可惜,由於每一個應用程式的自訂解決方案數量、各種方式及資料模型化所需步驟都不一樣,所以問題不斷擴大。產業開始出現一致的需求,亦即要定義及開發一種應用程式層級的網域模型,且要與存放區的邏輯模型明確區分。於是,Entity Framework 就問世了。
EDM (請參閱 [圖 1] 所說明的範例) 可讓網域模型的定義與組織考量資料的方式及其使用資料的方式一致,而不是與儲存資料的方式一致。開發 EDM 的主要目標,也是要成為 Microsoft 的開發人員和伺服器技術之間的核心資料模型。
圖 1 部落格資料庫的範例實體資料模型 (按一下影像以放大圖片)
使用單一核心資料模型,應用程式的維護工作就得以簡化。當此目標實現之後,EDM 便可用來定義一種模型,且不只適用於建置在 ADO.NET Entity Framework 之上的自訂應用程式,也可做為報告及視覺化應用程式、內部網路入口網站應用程式或工作流程應用程式的輸入。
EDM 與 ER 模型類似,也使用兩個主要概念:實體 (事物) 和那些實體之間的關係 (或關聯)。在思考實體和關聯執行個體的儲存時,或那些執行個體之集合 (Set) 作業的結束時,都需要集合 (Set) 的概念。因此,一言以蔽之,實體存在於 EntitySets 中,而關聯則存在於 AssociationSets 中。
定義在 EDM 中的最終結構性概念是 EntityContainer 的概念,它會定義前述執行個體及關係集合 (Set) 的結束。結合這些簡易概念,開發人員就可以定義一種網域模型,以對應回到保存層及應用程式本身使用的類別 (請注意,EDM 的保存層不一定要是關聯式的,雖然目前它是)。
在 EDM 中定義的每一個實體型別都可以包含兩種不同類型的成員 -- 定義實體的屬性 (類似資料庫中的資料行) 和巡覽屬性,後者可巡覽實體型別 (Entity Type) 所參與的關係 (通常以資料庫中的外部索引鍵表示)。除此之外,每一個實體型別都必須有不同的識別身分或索引鍵。[圖 2] 的 XML 片段即「部落格張貼 (Blog Post)」實體型別的說明。

圖 2 BlogPost 實體型別的定義
<EntityType Name="BlogPost">
<Key>
<PropertyRef Name="BlogPostID" />
</Key>
<Property Name="BlogPostID" Type="Int32" Nullable="false" />
<Property Name="BlogEntry" Type="String" Nullable="false" MaxLength="Max"
Unicode="true" FixedLength="false" />
<Property Name="BlogDate" Type="DateTime" Nullable="false" />
<Property Name="BlogTitle" Type="String" Nullable="false" MaxLength="500"
Unicode="true" FixedLength="false" />
<Property Name="BlogType" Type="Int32" Nullable="false" />
<Property Name="CityVisited" Type="String" MaxLength="200"
Unicode="true" FixedLength="false" />
<Property Name="CountryVisited" Type="String" MaxLength="200" Unicode="true"
FixedLength="false" />
<Property Name="DateVisited" Type="DateTime" />
<NavigationProperty Name="Blog" Relationship=
"MyTravelPostModel.FK_BlogPosts_Blogs"
FromRole="BlogPosts" ToRole="Blogs" />
<NavigationProperty Name="Pictures" Relationship=
"MyTravelPostModel.FK_Pictures_BlogPosts"
FromRole="BlogPosts" ToRole="Pictures" />
<NavigationProperty Name="Comments" Relationship=
"MyTravelPostModel.BlogComments"
FromRole="BlogPosts" ToRole="Comments" />
</EntityType>
實體型別的屬性可以是基本型別或複雜型別 (請參閱 [圖 3]),但在 Entity Framework 1.0 中,它們不可以是其他實體型別,或是基本型別或複雜型別的集合 (Collection)。實體型別的索引鍵是由這些屬性的子集組成。巡覽屬性可讓您巡覽一個實體到另一個實體的關係。

圖 3 Address 複雜型別的定義
<ComplexType Name="Address">
<Property Name="StreetAddress"
Type="String" MaxLength="50" />
<Property Name="Address2"
Type="String" MaxLength="50" />
<Property Name="City"
Type="String" MaxLength="50" />
<Property Name="Region"
Type="String" MaxLength="50" />
<Property Name="PostalCode"
Type="String" MaxLength="50" />
<Property Name="Country"
Type="String" MaxLength="50" />
</ComplexType>
如先前所討論,關係可呈現為該關係某一方的每一個實體型別上的巡覽屬性。關係本身是 EDM 內的第一等公民,且會明確定義為 EDM 內的關聯 (Association):
<Association Name="FK_Friends_People">
<End Role="People" Type="MyTravelPostModel.Person" Multiplicity="1" />
<End Role="Friends" Type="MyTravelPostModel.Friend" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="People">
<PropertyRef Name="PersonID" />
</Principal>
<Dependent Role="Friends">
<PropertyRef Name="PrimaryPersonID" />
</Dependent>
</ReferentialConstraint>
</Association>
簡言之,我們當初為何要建立新的資料模型技術?雖然在 EDM 之前已有一些資料模型技術或語言存在,但沒有一個能夠符合 Microsoft 嘗試完成的主要目標,也沒有一個能夠使常用的實體關係模型可執行。本團隊調查了許多現有的資料模型技術,但發現它們全都非常特殊或著重於特定問題領域,於是開始開發 EDM,來建立一個符合這些目標並可真正做為一組開發人員和伺服器技術之核心資料模型的模型。
為何要以 XML 描述 EDM?
經過仔細考量之後,XML 獲選為 EDM 的首選序列代表。擁有定義完善的 XML 格式,可讓開發人員和協力廠商進行此格式的轉換,及載入 Entity Framework 的中繼資料執行階段,其方式為透過產生 XML 檔 (或資源) 或從動態產生的 XML 表示中載入。不過,可想而知,也可以建立 EDM 的其他表示,而且當產品隨未來版本演進時,也會持續出現替代表示。
現行 EDM 文法定義於產品隨附的 XML 結構描述定義語言 (XSD)。不過,大部分人應該不會手動開發 XML,而是使用 Visual Studio 提供的工具。然而,本團隊聽說有人對定義域專屬語言 (DSL) 及 EDM 模型的替代保存機制 (一般資料庫) 感興趣之後,正在評估未來版本擴充的選項。
誰會想要另一個新的查詢語言?
關於 EDM 開發的最後一個問題是,為何要建立新的查詢語言?為何不使用現有的語言?當我再進一步深入探討 EDM 之後,答案就呼之欲出了。
到目前為止,我討論過為何要建立 EDM 及 EDM 所使用的各種建構,還有該模型是從實體關係模型傳下來的事實。在建立這個模型時,目標包括要完全對應到基礎資料存放區,同時還要代表開發人員在設計程式時可善用的應用程式層級網域模型,因此 EDM 必須能夠將繼承和多型之類的概念模型化。由於現行關聯式查詢語言不支援繼承式查詢、關係巡覽或多型結果的傳回,因此必須由新的查詢語言來滿足這些需求。
於是誕生了 Entity SQL (ESQL),這是一種新的 SQL 方言,它增加了根據先前 SQL 方言不支援的概念來查詢的能力。ESQL 延伸了現有的 SQL 語言的方式,與 EDM 延伸資料庫所使用關聯式模型的方式十分類似。此外,ESQL 亦不受限於任何特定後端資料庫的語法,所以僅需要寫入查詢 (及/或應用程式) 一次,而不需要管目標後端資料庫是哪一種資料庫。在下列範例中,我將探討一個簡易 ESQL 查詢,其中會擷取部落格中至少有一個張貼的所有部落格,以及相關聯人員 (就我的模型而言,這指的是部落格擁有者):
select c, c.Person
from travelEntitiesGeneral.Blogs as c
where c.BlogPosts.Count > 0
實作 EDM
ADO.NET Entity Framework 是 ADO.NET 的進化,也是 EDM 的第一個具體實作,在針對關聯式資料庫開發時,可提供更高階的抽象層次。在 1.0 版中,團隊將重點放在建置平台的基礎上,且要超越 ORM,讓開發人員可以利用極有彈性的對應來處理概念模型或物件模型,以及因應基礎存放區的分歧性。
這種彈性以及與基礎存放區的分歧性,是容許資料庫和應用程式個別發展的關鍵。當資料庫結構描述變更時,Entity Framework 會隔離應用程式,使其免受變更的影響,因此,通常您不需要改寫應用程式,只要在必要時更新對應檔案以因應變更。
開始發展 ADO.NET 平台時,Entity Framework 是建置在現有的 ADO.NET 2.0 提供者模型之上,且有稍微更新現有的提供者,以支援新的 Entity Framework 和 ADO.NET 3.5 的功能。我們選擇在現有的 ADO.NET 提供者模型之上實作,以確保開發社群熟悉此提供者模型。
[圖 4] 說明此架構。請注意,可接受的結構描述包括 Conceptual Schema Definition Language (CSDL)、Mapping Schema Language 及 Storage Schema Definition Language (SSDL)。另外還要注意,Entity Framework 包括一個更新的 SqlClient 資料提供者 (SqlClient Data Provider),其中支援標準命令樹 (Canonical Command Trees,CCT)。
圖 4 ADO.NET Entity Framework 架構 (按一下影像以放大圖片)
EntityClient
後來,Entity Framework 在這些 ADO.NET 3.5 提供者之上,引進了新的 ADO.NET 提供者 -- EntityClient。EntityClient 與您慣用的 ADO.NET 提供者看起來十分類似,它會提供第一個抽象層,讓開發人員能夠根據 EDM,使用標準 Connection、Command 及 DataReader 物件來執行查詢。它還多加了一個用戶端檢視引擎 (Client View Engine),需要這個引擎才能將根據 EDM 定義的網域模型,對應到基礎關聯式資料庫結構描述。EntityClient 還可以讓開發人員在必要時使用 ESQL 查詢字串,來處理資料列及資料行格式的實體,而不需要產生類別來代表概念結構描述。
如果您檢視 [圖 5] 所使用的 EntityClient,就會發現我建立了 EntityCommand 來接受 ESQL 查詢字串,然後會針對我的 EDM 來執行此命令。其中會剖析已 EntityCommand 所提供的查詢字串,並建立 CCT。

圖 5 使用 ESQL 查詢 EntityClient
using (EntityConnection conn = new
EntityConnection("name=travelEntitiesGeneral"))
{
conn.Open();
EntityCommand cmd = conn.CreateCommand();
cmd.CommandText = @"select c.BlogID
from travelEntitiesGeneral.Blogs as c
where c.BlogPosts.Count > 0";
EntityDataReader reader =
cmd.ExecuteReader(CommandBehavior.SequentialAccess);
while (reader.Read())
{
Console.WriteLine("BlogID = {0}", reader["BlogID"]);
}
conn.Close();
}
在第一個階段,命令樹仍然會根據 EDM 來表示。用戶端檢視引擎 (Client View Engine) 會採用資料庫系統中具體化檢視的理論,並將這些理論應用到資料存取層,以在命令樹中應用對應轉換來產生一個命令樹,其中會根據基礎邏輯儲存模型來表示相同的作業,並移除任何非關聯式的概念 (例如關係、繼承及多型)。接著這個新轉換的命令樹會交給 ADO.NET 3.5 提供者服務,而這會傳回一個 DbCommand 來封裝基礎存放區的原生 SQL,然後執行並將結果傳播回到堆疊中。
在定義用戶端檢視引擎 (Client View Engine) 用來進行 EDM 與邏輯資料庫結構描述之間轉換所使用的對應時,有幾個不同選項。對應可使用一種宣告式 XML 文法 Mapping Specification Language (MSL) 來指定,這可透過手動編寫 XML 程式碼或使用 Visual Studio 提供的實體對應工具 (Entity Mapping Tools) 來建立及編輯 (請參閱 [圖 6])。

圖 6 MSL -- EntitySetMapping 範例
<EntitySetMapping Name="BlogPosts">
<EntityTypeMapping TypeName="IsTypeOf(MyTravelPostModel.BlogPost)">
<MappingFragment StoreEntitySet="BlogPosts">
<ScalarProperty Name="BlogPostID" ColumnName="BlogPostID" />
<ScalarProperty Name="BlogEntry" ColumnName="BlogEntry" />
<ScalarProperty Name="BlogDate" ColumnName="BlogDate" />
<ScalarProperty Name="BlogTitle" ColumnName="BlogTitle" />
<ScalarProperty Name="BlogType" ColumnName="BlogType" />
<ScalarProperty Name="CityVisited" ColumnName="CityVisited" />
<ScalarProperty Name="CountryVisited"
ColumnName="CountryVisited" />
<ScalarProperty Name="DateVisited" ColumnName="DateVisited" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
編譯後的 MSL 會讓 Entity Framework 產生必要的查詢及更新檢視,然後在用戶端檢視引擎 (Client View Engine) 中使用這些檢視,來將根據 EDM 定義的查詢轉換成邏輯儲存結構描述。
表示此對應或局部對應的另一選項,是透過 ESQL 查詢的使用。在此情況下,當開發人員使用 ESQL 來表示查詢檢視 (Query View) 時,基礎結構會要求他們也在對應規格中定義伴隨的 Create、Update 及 Delete 對應。這是必要的,因為使用者可以在查詢檢視 (Query View) 中運用 ESQL 的功能,但是對應基礎結構並無法為該查詢檢視產生相對應的更新檢視,因此定義的檢視有可能並沒有任何有效的更新檢視。
物件服務
在 EntityClient 提供者之上,Entity Framework 加入了另一組抽象層以允許物件的開發,而非 EntityClient 傳回的不具型別資料記錄。這是常被視為 ORM 的一層,其中會產生資料模型中所定義型別的 CLR 執行個體,讓開發人員能夠使用 LINQ 或 ESQL 來查詢那些物件。這剛好也是吸引了在市場中尋求可用 ORM 技術的開發人員,來使用 Entity Framework 技術的層面。
如 [圖 1] 所示,物件服務 (Object Services) 層的高階功能是為了要接受應用程式中的 ESQL 或 LINQ 查詢,將查詢運算式傳遞至下方的 EntityClient,並傳回 IEnumerable<T>。然而,若進一步探索,您會發現物件服務層的核心是 ObjectContext,代表應用程式和基礎資料存放區之間互動的工作階段。
ObjectContext 是開發人員使用的主要建構,以查詢、加入及刪除其實體的執行個體,並將新的狀態存回到資料庫。[圖 7] 顯示如何建立及使用 ObjectContext 來查詢實體、操作實體及儲存變更 (SaveChanges)。此範例使用 ESQL 做為查詢語言。

圖 7 使用 ObjectContext
using (ObjectContext context = new ObjectContext("name=travelEntities"))
{
//--- create a query for customers
ObjectQuery<Person> personQuery = context.CreateQuery<Person>(
@"select value c from travelEntitiesGeneral.People
as c where c.PersonID == 1");
//--- by enumerating the query will be implicitly executed
//--- against the store and you can now work with an
//--- IEnumerable<Customer>
foreach (Person c in personQuery)
{
//--- dereference anything you like from Customer
Console.WriteLine(c.PersonID + ": " + c.Name);
c.Name = "New Name";
}
try
{
context.SaveChanges();
}
catch (OptimisticConcurrencyException opt)
{
// catching this exception allows you to
// refresh travelEntities with either store/client wins
// project the travelEntities into this failed travelEntities.
var failedEntities = from e3 in opt.StateEntries
select new { e3.Entity };
// Note: in future you should be able to just pass
// the opt.StateEntities
// in to refresh.
context.Refresh(RefreshMode.ClientWins, failedEntities.ToList());
context.SaveChanges();
}
}
透過物件服務的使用,可為開發人員簡化物件在記憶體中變更時的追蹤,以及簡化將變更存回到資料庫的程序。物件服務會利用 ObjectStateManager,來追蹤記憶體中執行個體的目前狀態,以及追蹤每一個執行個體從存放區擷取時的初始狀態,讓 Entity Framework 能夠在資料送回到資料庫時套用最佳並行處理。藉由對 ObjectContext 叫用 SaveChanges 方法,即可輕鬆地將追蹤的變更儲存及送回到資料存放區。
到目前為止,我大致討論了 ObjectContext,我的範例也展示了基底 ObjectContext 的使用,當您有取用 EDM 模型的動態工具或應用程式時,通常會使用到它。然而,使用 Visual Studio 做為開發環境時,開發人員會發現強型別 ObjectContext 的更多優點,因為可加入屬性和方法來呈現目標 EDM 專屬的功能。
[圖 8] 顯示使用強型別 ObjectContext 建立的查詢。此範例示範如何使用 LINQ 做為查詢語言。使用強型別 ObjectContext 會公開每一個 EntitySet 的屬性,使它們更加明顯;例如,以 travelEntities.BlogPosts 取代 travelEntities.CreateQuery<BlogPost>("travelEntitiesGeneral.BlogPosts")。

圖 8 使用強型別 ObjectContext 建立的查詢
using (MyTravelPostEntities travelEntities = new MyTravelPostEntities())
{
// get the latest blog post, with the comments and the people
// I'm querying for all the blog posts that are related to this blog.
// I want to include the comments and the people who wrote the
// comments.
// I also want only the most recent posting.
// Note: Since we use the EntityKey that is put on the EntityReference
// we can either do a tracking query or use span.
BlogPost post = (from bp in
travelEntities.BlogPosts
.Include("Comments.Person")
.Include("Blog")
where bp.Blog.BlogID == requestedBlog.BlogID
orderby bp.BlogDate descending
select bp).First();
return post;
}
相對於字串型查詢,LINQ to Entities 是物件服務上非常精簡的一層,它可以直接在程式語言內提供查詢機能 (請參閱 [圖 8])。在此案例中,ObjectQuery 類別會實作 IQueryable,讓它採用 LINQ 運算式樹狀目錄,在 Entity Framework 中以 CCT 查詢運算式來發送查詢,其方式與物件服務將 ESQL 查詢傳遞至 EntityClient 提供者的方式一樣。
使用 Entity Framework 進行多層式架構 (N-Tier) 的開發
雖然本文的主要目標不是要討論多層式架構 (N-Tier) 的開發,但它在使用 Entity Framework 進行開發時的確值得探討,所以在此略微談論。在 1.0 版中,Entity Framework 在一些主要案例中有支援多層式架構 (N-Tier) 的開發。這些包括 ADO.NET 資料服務或 Windows® Communication Foundation (WCF) 的使用,還有將實體序列化、附加,以及中斷 ObjectContext 與實體之連結的能力。顯然這些並非多層式架構 (N-Tier) 之開發的唯一方法;不過,這些卻是團隊在第 1 版選擇集中注意力的解決方案,在第 2 版和未來則增加了其他案例,例如更接近資料集的體驗。[圖 9] 說明我所談論的內容。

圖 9 多層式架構 (N-Tier) 應用程式中的 ADO.NET 資料服務
static Uri baseService = new
Uri("http://localhost:17338/MyTravelPostService.svc");
MyPeople2Entities context = new MyPeople2Entities(baseService);
// get the comment that is being marked for deletion
// and get the view state blog post.
BlogPost post = (BlogPost)ViewState["BlogPost"];
// move the comment to the deleted comment selection.
Comment deletedComment = post.Comments[e.RowIndex];
// call the DeleteComment service
context.AttachTo("Comments", deletedComment);
context.DeleteObject(deletedComment);
DataServiceResponse r = context.SaveChanges();
// reload page so that F5, refresh doesn't update all this data.
ReloadPage();
ADO.NET 資料服務是代表性狀態傳輸 (Representational State Transfer,REST) 架構式的具體實現 (每一個資源代表系統中的一個「名詞」,這是可透過統一資源識別元 (URI) 唯一定址的項目),且可在任何 IQueryable 實作上進行多層式架構 (N-Tier) 應用程式的開發。利用 ADO.NET 資料服務,您就可以在網路上針對執行個體進行查詢和其他工作。ADO.NET 資料服務支援 Create、Read、Update 及 Delete 的各種 HTTP 動詞命令,並提供用戶端抽象層來協助開發人員實作其解決方案。
多層式架構 (N-Tier) 案例的第二個選項,是搭配 WCF 來使用 Entity Framework,這樣即可將實體序列化、附加及中斷 ObjectContext 與實體的連結。[圖 10] 顯示如何在此案例中附加至 ObjectContext。

圖 10 附加至 ObjectContext
// the creation of the travel MyTravelPostEntities opens the connection
// and sets up all the metadata information automatically for you.
using (MyTravelPostEntities travelEntities = new MyTravelPostEntities())
{
// attach the comment and delete.
travelEntities.Attach(deleteComment);
// call delete on the object
travelEntities.DeleteObject(deleteComment);
try
{
travelEntities.SaveChanges();
}
catch (OptimisticConcurrencyException opt)
{
// catching this exception allows you to
// refresh travelEntities with either store/client wins
// project the travelEntities into this failed travelEntities.
var failedEntities = from e3 in opt.StateEntries
select new { e3.Entity };
travelEntities.Refresh(RefreshMode.ClientWins, failedEntities.ToList());
travelEntities.SaveChanges();
}
}
根據預設,任何從 Visual Studio 中的 EDM 產生的 CLR 類別,或是使用 edmgen.exe (Entity Framework 所附的命令列工具) 產生的 CLR 類別,都是可由 XML 序列化、二進位序列化的類別,而且都是資料合約 (其中預設具有 DataMembers 屬性 (Attribute) 的 Navigation 屬性 (Property)),因此可以建立 ASMX Web 服務,以及在檢視狀態或 WCF 服務中使用 Entity 執行個體。
和大部分 ORM 一樣,Entity Framework 目前並不支援資料操作語言 (Data Manipulation Language,DML) 的建立 (create)、更新 (update) 或刪除 (delete) 等作業。所做的變更必須套用到記憶體中的物件,若要建立持續的完整圖形,則需要對資料庫進行往返作業。
有一種方法可避免這種情況,即使用 ObjectContext 提供的附加 (Attach) 功能。使用附加 (Attach) 功能即可告訴基礎結構實體 (Entity) 已存在,而且應該在記憶體中執行一組作業,然後發送變更。如需使用 Entity Framework 進行多層式架構 (N-Tier) 之開發的詳細資訊,請搜尋 MSDN® Library,因為很快就會加入更多內容。
只不過是另一個 ORM?
到目前為止,許多人認為 Entity Framework 只不過是市場中的另一個 ORM 而已,若只看過該產品的第一版,那麼這種看法是可以理解的。就這樣的角度而言,該產品到目前為止所涵蓋的許多部分,都是 ORM 所處理的一組核心案例。不過,到目前為止的許多分析指出,Entity Framework 也不一定能夠如您所想地涵蓋市場中其他 ORM 的所有功能,這是事實。
Microsoft 在這塊領域的投資目標,是要延伸傳統 ORM 產品,而 Entity Framework 正是更廣泛的 EDM 策略的第一步,稍後我將進一步說明這一點。正如我在本文開頭提過的,EDM 會建立更高階的網域模型,甚至超越 Entity Framework 和傳統 ORM 的境界。我們預期,經過未來幾個版本的 Microsoft .NET Framework、Visual Studio、SQL Server® 和其他 Microsoft 技術之後,您就可以開始看到採用 EDM 的人數有所增加。
正如本文所討論的許多產品決策中所看到的,這主要是受到這項預期和 EDM 趨勢的整個願景所帶動。在做出許多決策時,其明確意圖是希望由 Reporting Services 和 Analysis Services 之類的技術採用。藉由讓服務得以透過一致的網域模型提供,即可為客戶帶來很大的益處。
此願景的第一步,就是要隨 Visual Studio 2008 SP1 同時發行的 Entity Framework 及 ADO.NET 資料服務。可為開發人員提供 REST 應用程式優勢的 ADO.NET 資料服務,將成為 (在 Entity Framework 之外) 使用 EDM 做為其中繼資料交換格式而建立的第一個發行產品。
為了配合此產品的發行,Microsoft 在 MIX 2008 示範了一些不同的 Windows Live™ 屬性,其中使用 ADO.NET 資料服務通訊協定和 EDM 來公開其資料。同樣地,因為現在我們開始要規劃下一版的 SQL Server 和 Visual Studio,所以團隊會以 EDM 和 Entity Framework 為核心,致力於實現更優異的整體開發體驗。