[VS2010] ADO.NET Entity Framework 新功能:外來鍵的支援 (Foreign Key Support)

[VS2010] ADO.NET Entity Framework 新功能:外來鍵的支援 (Foreign Key Support)

前陣子在撰寫 Model First 的文章時,有個同好在噗浪上問筆者:ADO.NET Entity Framework 2.0 是否已支援 FK (Foreign Key) ? 筆者當時告訴他:是的。今天咱們就來看看這個部份。

 

Foreign Key 是設計資料庫時常見的一種鍵值,它定義了與主表 (Master) 與明細表 (Detail) 之間的關聯性,像是訂單主檔和訂單明細檔之間的作法。

有了 FK 之後,就可以實作參考完整性 (Reference Integrity),以及像是串聯更新 (Casceding Update) 與串聯刪除 (Cascading Delete) 等保證值域完整,並符合正規化的機制。只要有設計過資料庫的人對這個一定很有感覺。

在 Entity Framework 1.0 時,雖然可以建立 association,但是卻沒有辦法在 SaveChanges() 時依 FK 來輸入對應的資料,這是 Entity Framework 1.0 設計時的一個缺陷,例如下列的程式碼就是插入明細表的一支程式:

 

==========================================================================
Orders order = new Orders { OrderID = item.Identity.OrderID };
Products product = new Products { ProductID = item.Identity.ProductID };
Order_Details orderDetails = new Order_Details { Order = order, Product = product, …};

// We only need to add the order detail because it keeps the reference of the order and product
_context.AddtoOrder_Details(orderDetails);
==========================================================================

 

但依照一般 Master/Detail 的概念來說,程式碼其實應該要是這樣:

 

==========================================================================
Orders order = new Orders { OrderID = item.Identity.OrderID };
Products product = new Products { ProductID = item.Identity.ProductID };
Order_Details orderDetails = new Order_Details { Order = order, Product = product, …};

// add order and order details.
order.Order_Details.Add(orderDetails);
context.Orders.AddObject(order);

context.SaveChanges();
==========================================================================

 

其實這是因為要實作 Foreign Key 要考量的事情很多,最直接的考量就是資料插入的順序,在 ObjectContext.SaveChanges() 呼叫 Provider 以產生 SQL 指令時,就需要先按照 PK->FK 的順序插入資料,而在 PK 尚未插入資料前,FK 無從得知 PK 的值,也就是說若要達成 FK 的能力,Entity Framework 必須要能夠在插入 PK 值時取得資料庫中的 PK 值,才可以由 FK 來接手插入資料。這個問題在 Entity Framework 1.0 時尚未獲得解決,但到了 Entity Framework 2.0,筆者很高興的看到它解決了,這樣讓程式碼更加的直覺,而不用還得依靠一個獨立的方法來插入 FK 的物件。

 

例如這樣的一個資料模型:

 

image

  

這個資料結構顯示 Customer 和 Orders 之間存在著一對多的關係,這是在 Model First Design 那篇文章中拉出來的資料結構,但尚未設定 FK 關聯 (FK Association) 此時可以在 1-* 那一條線上連按兩下 (Double Click),就會看到設定參考完整性的視窗:

 

image

 

Principal 是主資料表 (Master),Dependent 則是明細表 (Detail),設定好後按 OK 即可建立參考完整性的資訊,表示 FK 功能正式生效。

另一個加入 FK 的方法是,在 Model Designer 圖形介面的空白處按右鍵,然後選擇 Add > Association…:

 

image

 

然後在設定的對話盒中,將 Add foreign key properties to the [table] Entity 打勾 (預設就是打勾的) 即可。

 

image

 

有了關聯的設定後,就可以運用下列的程式碼去加入主從式資料了:

 

using (ModelFirstContainer context = new ModelFirstContainer())
{
    Customers customer = new Customers() { ... };
    customer.Orders.Add(new Orders() { ... });
    context.AddToCustomers(customer);
    context.SaveChanges();
}

 

參考資料:

Foreign Key Relationships in the Entity Framework

http://blogs.msdn.com/adonet/archive/2009/11/06/foreign-key-relationships-in-the-entity-framework.aspx