簡體   English   中英

實體框架4每個層次結構表 - 如何定義兒童的導航屬性?

[英]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關聯也是這個條件。

但我不明白。 所有實體的鑒別器都是唯一的(我有三重檢查),我認為這是一個有效的場景:

  1. 縣有一個州,由StateLocationId(Locations表)表示
  2. ZipCode有一個State,由StateLocationId(Locations表)表示

這在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM