2010-12-15 205 views
1

我有一個表在我的數據庫中存儲的項目:建模相關的實體與SQL Server和實體框架

Items 
------- 
ItemID 
Name 
... 
Etc 

和一個單獨的表存儲的兩個不同項目的PK從第一個表。我希望能夠列出一個項目,然後列出任何數量的相關項目。我試着尋找例子,但還沒有發現太多令人驚訝的...

RelatedItems 
------------ 
ItemID 
RelatedItemID 

如果我有四個產品,ID分別爲1,2,3和4 ...和1是與2 3我可能看起來像這樣的數據:

ItemID RelatedItemID 
1  2 
1  3 
4  1 

我則模擬他們在Entity Framework設計和設計師自動添加從項目表與自身關聯(多對多)。如果我在Item#1上使用第一個屬性,設計師還添加了兩個導航屬性,我得到Item#1在第一列中的所有項目,如果使用第二個屬性,則獲取項目#1所在的所有項目第二列。

但是我只是想擁有一個導航屬性,我可以說Items.RelatedItems並返回上述兩個屬性合併時的所有項目。我知道在事後我可以加入這兩項結果,但我不禁認爲自己做錯了事,並且有更好的辦法。

希望這已經足夠清楚了。

回答

1

聽起來像SQL模式只是不是很好的建模你正在尋找的概念。如果要建立方向關係(項目A與項目B相關,但項目B可能與項目A相關或可能不相關),那麼您選擇的模式將很有效。如果您正在尋找分組風格的關係(項目A和B在同一組中),我可以考慮使用不同的方法。但我想不出一種使用傳統關係數據庫建立固有雙向關係的好方法。

一些解決方法可能是使用連接兩個結果的View或使用觸發器來確保從A到B的每個映射都具有從B到A的對應映射,以便這兩個屬性始終返回相同的物體。

0

如果你有一個項目的實例,調用它的項目,那麼下面會給你相關的項目......在項目

item.RelatedItems.Select(ri => ri.Item); 

你RelatedItems屬性(即你提到的第一個導航屬性)將是一個RelatedItem對象的集合,每個對象都有其自己的兩個導航屬性,其中一個將被命名爲Item,並將成爲相關項目的鏈接。

請注意,這是空氣代碼,因爲我不在任何可以測試此功能的前面,但我認爲這將按照您的要求進行。

如果你想更簡單,你可以寫一個擴展方法的收官選擇(),這樣的事情...

public static IEnumerable<Item> RelItems(this Item item) { 
    return item.RelatedItems.Select(ri => ri.Item); 
} 

然後,你可以只是做...

item.RelItems(); 

請注意,我無法命名擴展方法RelatedItems,因爲這會與EF爲第二個表創建的導航屬性衝突。這可能不是該表的好名字,因爲它不是實際的項目,而是項目的ID。無論哪種方式,上面的代碼應該工作。