[英]Entity Framework 4 Table Per Hierarchy - How To Define Navigational Properties On Children?
我目前使用Table Per Type(TPT)實現了Entity Framework 4.0模型,但是存在一些性能問題(許多LOJ / CASE語句),以及兩個特定域區域之間的問題映射(多個到 - 許多)。
我決定嘗試TPH。
我有一個名為“ Location ”的實體,它是抽象的 ,是所有其他實體的基礎。
然后我有“ 國家 ”,“ 城市 ”,“ 州 ”,“ 街道 ”等,這些都來自位置。
“ LocationType ”是判別者 。
該部分工作正常,但我在嘗試為派生類型定義導航屬性時遇到問題。
例如,“ 州 ”有一個“ 國家 ”,所以我應該能夠這樣做:
var state = _ctx.Locations.OfType<State>().Include("Country").First();
var countryForState = state.Country;
但這需要在“州”派生實體上稱為“國家”的導航屬性。 我該怎么做呢? 當我從數據庫生成模型時,我有一個表,所有FK指向同一個表中的記錄:
(注意:我在DB中手動創建了這些FK)。
但是FK被定位為“ 位置 ”實體上的導航,那么如何將這些導航屬性下移到派生實體? 我不能復制+粘貼導航,我不能“創建新的導航屬性”,因為它不會讓我定義開始/結束角色。
我們如何做到這一點?
如果我們可以先建立模型,或者我們必須從數據庫開始,修復模型然后重新生成數據庫,那么TPH也不清楚。 我還沒有在互聯網上找到一個關於如何使用TPH定義兒童導航的好例子。
注意: 我不想先執行代碼 。 我目前的解決方案是TPT與EDMX,以及純POCO,我希望不影響域模型/存儲庫(如果可能),只需更新EF模型/數據庫。
編輯
仍然沒有解決方案 - 但是我試圖做模型優先,並做Add - > New Association,這實際上允許我向派生實體添加導航。 但是當我嘗試“從模型生成數據庫”時,它仍然嘗試為“Location_Street”,“Location_Country”等創建表。這幾乎就像TPH不能先完成模型。
編輯
這是我目前的型號:
我目前得到的驗證錯誤:
錯誤1錯誤3002:從第359行開始映射片段時出現問題:潛在的運行時違反表位置的鍵(Locations.LocationId):列(Locations.LocationId)在概念方面映射到EntitySet NeighbourhoodZipCode的屬性(NeighbourhoodZipCode.Neighbourhood.LocationId)但它們並不構成EntitySet的關鍵屬性(NeighbourhoodZipCode.Neighbourhood.LocationId,NeighbourhoodZipCode.ZipCode.LocationId)。
只是想我會繼續編輯這個問題,編輯關於我目前所處的位置。 我開始懷疑具有自引用FK的TPH是否可能。
編輯
所以我想出了上面的錯誤,那是因為我錯過了Neighborhood-ZipCode的連接表多對多。
添加連接表(並將導航映射到該表)解決了上述錯誤。
但現在我得到這個錯誤:
錯誤3032:從第373行,第382行開始映射片段時出現問題:條件成員的Locations.StateLocationId'具有重復的條件值。
如果我看一下CSDL,這里是“CountyState”的關聯映射(一個州有很多縣,一個縣有一個州):
<AssociationSetMapping Name="CountyState" TypeName="Locations.CountyState" StoreEntitySet="Locations">
<EndProperty Name="State">
<ScalarProperty Name="LocationId" ColumnName="StateLocationId" />
</EndProperty>
<EndProperty Name="County">
<ScalarProperty Name="LocationId" ColumnName="LocationId" />
</EndProperty>
<Condition ColumnName="StateLocationId" IsNull="false" />
</AssociationSetMapping>
這是Condition ColumnName="StateLocationId"
,這是抱怨,因為ZipCodeState
關聯也是這個條件。
但我不明白。 所有實體的鑒別器都是唯一的(我有三重檢查),我認為這是一個有效的場景:
這在TPH中無效嗎?
所以我解決了我的一些問題,但我碰到了一堵磚牆。
首先,當您在數據庫端創建自引用FK時,當您嘗試“從數據庫更新模型”時,實體框架會將這些導航屬性添加到主基類型,因為它沒有明確的TPH感 - 您需要在模型方面做到這一點。
但是,您可以手動將導航屬性添加到子類型。
WRT此錯誤:
錯誤3032:從第373行,第382行開始映射片段時出現問題:條件成員的Locations.StateLocationId'具有重復的條件值。
那是因為我有一個名為“Location_State”的FK我試圖用於“ZipCode_State”關系,以及“City_State”關系 - 這不起作用(仍然不知道為什么)。
所以要解決這個問題,我必須添加額外的列和額外的FK - 一個叫做“ZipCode_State”,另一個稱為“City_State” - 顯然它必須是導航和物理FK之間的1-1。
Location.LocationType沒有默認值,也不可為空。 存儲實體數據需要列值。
那是我的鑒別領域。 在數據庫方面,它不可為空 。
我讀了關於這個問題的線索,他們說你需要將關系從0 .. *更改為1 .. * - 但我的關系已經是1 .. *。
如果你查看我上面的“Locations”實際數據庫表,所有FK都可以為空(它們必須是)。 因此我開始懷疑我的關系是否應為0 .. *。
但由於TPH,它們可以為空 - 並非所有“地點”都有“國家”。 但如果該位置是“城市”,那么它就有了“國家”。
這個問題讓我的感受更加安慰: ADO EF - 錯誤映射TPH中派生類型之間的關聯
我實際上正在嘗試這種解決方法(在我遇到它之前),並且解決方法對我不起作用。 我甚至嘗試將所有關系從1 .. *更改為0 .. *,但仍然沒有運氣。
在這里浪費了太多時間,我回到了TPT。
在一天結束時,使用TPH我會有一個可笑的大表,有很多冗余的可空列。 加入方式,效率更高。 但至少對於TPT,我不需要有可空和自我引用的FK。
如果有人能解決這個問題,請告訴我。 但在那之前,我堅持使用TPT。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.