EDM 建立於 Peter Chen 的 **ER 模型** 之上,將抽象層級提升至**概念模型**,脫離儲存細節。三大核心概念:
BlogPost),含屬性 (標量/複雜型別) 與導航屬性 (關聯)。ObjectContext 的查詢入口。
<EntityType Name="BlogPost">
<Key><PropertyRef Name="BlogPostID" /></Key>
<Property Name="BlogPostID" Type="Int32" Nullable="false" />
<Property Name="BlogTitle" Type="String" MaxLength="500" />
<NavigationProperty Name="Blog" Relationship="FK_BlogPosts_Blogs" FromRole="BlogPosts" ToRole="Blogs" />
<NavigationProperty Name="Comments" Relationship="BlogComments" FromRole="BlogPosts" ToRole="Comments" />
</EntityType>
<Association Name="FK_BlogPosts_Blogs">
<End Role="Blogs" Type="Model.Blog" Multiplicity="1" />
<End Role="BlogPosts" Type="Model.BlogPost" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Blogs"><PropertyRef Name="BlogID" /></Principal>
<Dependent Role="BlogPosts"><PropertyRef Name="BlogID" /></Dependent>
</ReferentialConstraint>
</Association>
傳統 SQL 不支援:**繼承查詢、導航屬性路徑、多型結果**。ESQL 延伸 SQL:
-- 查詢至少有一篇文章的部落格,並導航至作者
SELECT VALUE b, b.Person FROM travelEntities.Blogs AS b WHERE b.BlogPosts.Count > 0
VALUE 關鍵字投影實體實例而非匿名記錄。b.BlogPosts.Count 直接操作集合屬性。| 層級 | 組件 | 職責 | 典型 API |
|---|---|---|---|
| 儲存層 | SSDL + Provider (SqlClient) | 資料庫 Schema、原生 SQL 執行 | DbCommand, DbDataReader |
| 映射層 | MSL (Mapping Specification Language) | CSDL ↔ SSDL 雙向視圖轉換 | EntitySetMapping, AssociationSetMapping |
| 概念層 | CSDL + EntityClient | EDM 查詢、Client View Engine、命令樹 (CCT) | EntityConnection, EntityCommand, EntityDataReader |
| 物件層 | ObjectServices | 物質化、變更追蹤、LINQ to Entities、身分解析 | ObjectContext, ObjectQuery<T>, SaveChanges |
using (var conn = new EntityConnection("name=TravelEntities"))
{
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = "SELECT VALUE b FROM TravelEntities.Blogs AS b WHERE b.BlogPosts.Count > 0";
using (var rdr = cmd.ExecuteReader(CommandBehavior.SequentialAccess))
while (rdr.Read()) Console.WriteLine(rdr["BlogID"]);
}
適合**不需物質化**、高效能唯讀報表查詢。
using (var ctx = new TravelEntities()) // 強型別 ObjectContext
{
// LINQ to Entities
var post = ctx.BlogPosts
.Include("Comments.Person")
.Include("Blog")
.Where(p => p.Blog.BlogID == blogId)
.OrderByDescending(p => p.BlogDate)
.FirstOrDefault();
post.BlogTitle = "Updated";
ctx.SaveChanges(); // 單一交易寫入所有變更
}
Added/Modified/Deleted/Unchanged 狀態,支援樂觀並發 (OptimisticConcurrencyException)。ClientWins / StoreWins 衝突解決。EF 1.0 重點支援兩種方案:
/Blogs(1)/Comments)。$filter, $expand, $orderby 等 OData 查詢選項。DataServiceContext 追蹤變更,SaveChanges() 批次送出。
// 伺服端
public class TravelService : DataService
{
public static void InitializeService(IDataServiceConfiguration config)
=> config.SetEntitySetAccessRule("*", EntitySetRights.All);
}
// 客戶端刪除評論
var ctx = new TravelEntities(new Uri("https://host/TravelService.svc"));
var comment = (Comment)ViewState["Comment"];
ctx.AttachTo("Comments", comment);
ctx.DeleteObject(comment);
ctx.SaveChanges();
DataContractSerializer),導航屬性為 DataMember。Attach + DeleteObject + SaveChanges 完成持久化。
[ServiceContract]
public interface ITravelService
{
[OperationContract] void DeleteComment(Comment comment);
}
public class TravelService : ITravelService
{
public void DeleteComment(Comment comment)
{
using (var ctx = new TravelEntities())
{
ctx.Attach(comment);
ctx.DeleteObject(comment);
ctx.SaveChanges();
}
}
}
| 限制 | 現狀 | 規劃 |
|---|---|---|
| 批次 DML (Bulk Update/Delete) | 不支援,需逐筆物質化 | EF Core 已支援 ExecuteUpdate/Delete |
| Enum/空間型別 | EF4 開始支援 | 完整支援 |
| Lazy Loading 透明化 | 需虛擬屬性 + Proxy | Core 預設支援 |
| Code First / Migration | EF 4.1 / 4.3 引入 | Core 核心功能 |
Entity Framework 以 **EDM 為核心**,向下支援多資料庫 Provider、向上提供 EntityClient/ObjectServices/LINQ 多層抽象,**映射層 (MSL) 解耦領域模型與儲存結構**,實現「資料庫演進不改應用、應用演進不改資料庫」。N 層透過 Data Services/WCF 序列化實體並利用 Attach/Detach 管理狀態。雖 v1 功能未臻完善,但**架構願景清晰**:EDM 將成為 Microsoft 整個資料平台 (Reporting/Analysis/Integration) 的**通用語義模型**。