2011-04-21 31 views
2

我在設置關聯不包含所有主鍵值的兩個表之間的實體框架中關聯時遇到問題。與實體框架的非鍵控關聯

例如我有兩個表(這是一個人爲的例子,但足以代表我的,我不能改變實際的數據庫)

------Items------ ---Orders---- 
----------------- ------------- 
* ItemId  - * OrderId - 
* EffectiveDate - - OrderDate - 
- Name   - - ItemId - 
----------------- ------------- * denotes primary key field 

理想情況下,我想對訂單的屬性,表示這是有效的訂購日期的項目,但是我可以與Order中的一個關聯一起生活到一個Items集合中,然後在Order上創建一個只讀屬性來選擇正確的Item。

編輯:數據庫和模型將是隻讀的,所以只讀解決方案是好的。

這是可能的實體框架? (或甚至LINQ to SQL?)

我相信有可能使用NHibernate(任何人都可以確認嗎?)但我一直用實體框架敲擊磚牆。到目前爲止,我所管理的唯一解決辦法是建立在部分類的屬性對於使用「hack」從訂單直接訪問的ObjectContext和查詢context.Items收集這樣

private IEnumerable<Item> Items 
{ 
    get 
    { 
     var ctx = this.GetContext(); 
     return from i in ctx.Items where i.ItemId == this.ItemId select i; 
    } 
} 

public Item Item 
{ 
    get 
    { 
     return (from i in Items 
       where i.EffectiveDate <= this.OrderDate 
       orderby i.EffectiveDate ascending 
       select i).First(); 
    } 
} 

順序是有更好的解決方案?

回答

2

問題是你的數據庫設計不正確,這些表之間沒有關係 - Order不能與Item有FK關係,因爲它的FK不包含Item的PK的所有部分。在數據庫中,可以通過在Item表中的ItemId上放置唯一索引來避免這種情況,但它會使您的組合PK冗餘,並且不能解決EF的問題,因爲EF不支持唯一鍵。多對多關係無法映射,因爲您缺少結表。

所以EF的答案是否定的。 linq-to-sql的答案也是一樣。

+0

謝謝,這正是我所懷疑的,但我覺得奇怪的是,實質上簡單的SQL連接會給實體框架帶來很多麻煩。 – Eamon 2011-04-21 11:43:20

+0

連接可能是可能的,但整個實體將變爲只讀(不更新,刪除,插入)。 – 2011-04-21 12:11:02

+0

我應該補充說我正在創建一個只讀模型(我會更新Q)。應用程序根本不會寫入這個特定的數據庫,所以只讀集合將非常適合這種情況。 – Eamon 2011-04-21 22:59:13

0

您可以使用方法並將上下文作爲參數,或者只是創建一個新的上下文(至少在LINQ to SQL中,這取決於你的用例,如果我的研究是有效的)。

但是,你正在嘗試創建一個條件鏈接,所以你將不得不寫一個代表這個條件的方法 - 框架基本上是做同樣的事情(即選擇帶有FK列ID的Item )。我不完全確定問題在做什麼?

我也完全由您ERD迷惑 - 它好像:

  • 項具有相同的ID,但隨着時間的推移不同的名字(我不會稱之爲在這種情況下,表「項目」)
  • 每個訂單爲一個項目
  • 您正在嘗試計算該訂單時項目的名稱。

出於好奇,這是正確的嗎?

基於您無法更改ERD的事實,您提到的方法可能是實現該方法的最佳方法(儘管您可能要將Items標記爲IQueryable<Item>)。

+0

這個例子是爲了說明這個問題而設計的,它可能會更容易在腦海中替代Item.Price而不是Item.Name,並調用表ItemPrices,但效果是相同的。真正的數據庫要複雜得多,設計也很糟糕,但是完全沒有辦法改變它的任何事情(即使這些表格明顯要與之相關,甚至沒有一個外鍵約束)表格本質上是記錄一個對象的時間狀態,我想在某個時間點檢索適當的記錄。 – Eamon 2011-04-21 11:54:53

+0

是的,所以我認爲我的答案適用於這種情況。你不能有條件的FK,所以你會想模仿框架的FK代碼並返回一個IQueryable,而不是IEnumerable。 – 2011-04-22 14:29:05