简体   繁体   English

实体框架4每个层次结构表 - 如何定义儿童的导航属性?

[英]Entity Framework 4 Table Per Hierarchy - How To Define Navigational Properties On Children?

I currently have a Entity Framework 4.0 model in place with Table Per Type (TPT), but there are a few performance issues (lots of LOJ's/CASE statements), as well as an issue mapping between two particular domain areas (many-to-many). 我目前使用Table Per Type(TPT)实现了Entity Framework 4.0模型,但是存在一些性能问题(许多LOJ / CASE语句),以及两个特定域区域之间的问题映射(多个到 - 许多)。

I've decided to try out TPH. 我决定尝试TPH。

I have an entity called " Location " which is abstract , and the base for all other entities. 我有一个名为“ Location ”的实体,它是抽象的 ,是所有其他实体的基础。

I then have " Country ", " City ", " State ", " Street ", etc which all derive from Location. 然后我有“ 国家 ”,“ 城市 ”,“ ”,“ 街道 ”等,这些都来自位置。

" LocationType " is the dicriminator . LocationType ”是判别者

That part is working fine, but i'm having issues trying to define navigational properties for the derived types. 该部分工作正常,但我在尝试为派生类型定义导航属性时遇到问题。

For instance, a " State " has a single " Country ", so i should be able to do this: 例如,“ ”有一个“ 国家 ”,所以我应该能够这样做:

var state = _ctx.Locations.OfType<State>().Include("Country").First();
var countryForState = state.Country;

But this would require a navigational property called "Country" on the "State" derived entity. 但这需要在“州”派生实体上称为“国家”的导航属性。 How do i do this? 我该怎么做呢? When i generate the model from the database, i have a single table with all the FK's pointing to records in the same table: 当我从数据库生成模型时,我有一个表,所有FK指向同一个表中的记录:

替代文字

(NOTE: I created those FK's manually in the DB). (注意:我在DB中手动创建了这些FK)。

But the FK's are placed as nav's on the " Location " entity, so how do i move these navigational properties down to the derived entities? 但是FK被定位为“ 位置 ”实体上的导航,那么如何将这些导航属性下移到派生实体? I can't copy+paste the navs across, and i can't "create new navigational property", because it won't let me define the start/end role. 我不能复制+粘贴导航,我不能“创建新的导航属性”,因为它不会让我定义开始/结束角色。

How do we do this? 我们如何做到这一点?

It's also not clear with TPH if we can do it model-first, or we HAVE to start with a DB, fix up the model then re-generate the DB. 如果我们可以先建立模型,或者我们必须从数据库开始,修复模型然后重新生成数据库,那么TPH也不清楚。 I am yet to find a good example on the internet about how to define navs on children with TPH. 我还没有在互联网上找到一个关于如何使用TPH定义儿童导航的好例子。

NOTE: I do not want to do code-first . 注意: 我不想先执行代码 My current solution has TPT with the EDMX, and pure POCO's, i am hoping to not affect the domain model/repositories (if possible), and just update the EF Model/database. 我目前的解决方案是TPT与EDMX,以及纯POCO,我希望不影响域模型/存储库(如果可能),只需更新EF模型/数据库。

EDIT 编辑

Still no solution - however im trying to do model-first, and doing Add -> New Association, which does in fact allow me to add a nav to the derived entities. 仍然没有解决方案 - 但是我试图做模型优先,并做Add - > New Association,这实际上允许我向派生实体添加导航。 But when i try and "Generate database from Model", it still tries to create tables for "Location_Street", "Location_Country" etc. It's almost like TPH cannot be done model first. 但是当我尝试“从模型生成数据库”时,它仍然尝试为“Location_Street”,“Location_Country”等创建表。这几乎就像TPH不能先完成模型。

EDIT 编辑

Here is my current model: 这是我目前的型号:

替代文字

The validation error i am currently getting: 我目前得到的验证错误:

Error 1 Error 3002: Problem in mapping fragments starting at line 359:Potential runtime violation of table Locations's keys (Locations.LocationId): Columns (Locations.LocationId) are mapped to EntitySet NeighbourhoodZipCode's properties (NeighbourhoodZipCode.Neighbourhood.LocationId) on the conceptual side but they do not form the EntitySet's key properties (NeighbourhoodZipCode.Neighbourhood.LocationId, NeighbourhoodZipCode.ZipCode.LocationId). 错误1错误3002:从第359行开始映射片段时出现问题:潜在的运行时违反表位置的键(Locations.LocationId):列(Locations.LocationId)在概念方面映射到EntitySet NeighbourhoodZipCode的属性(NeighbourhoodZipCode.Neighbourhood.LocationId)但它们并不构成EntitySet的关键属性(NeighbourhoodZipCode.Neighbourhood.LocationId,NeighbourhoodZipCode.ZipCode.LocationId)。

Just thought i'd keep editing this question with edit's regarding where i am currently at. 只是想我会继续编辑这个问题,编辑关于我目前所处的位置。 I'm beginning to wonder if TPH with self-referencing FK's is even possible. 我开始怀疑具有自引用FK的TPH是否可能。

EDIT 编辑

So i figured out the above error, that was because i was missing the join-table for the Neighbourhood-ZipCode many to many. 所以我想出了上面的错误,那是因为我错过了Neighborhood-ZipCode的连接表多对多。

Adding the join table (and mapping the navs to that) solved the above error. 添加连接表(并将导航映射到该表)解决了上述错误。

But now im getting this error: 但现在我得到这个错误:

Error 3032: Problem in mapping fragments starting at lines 373, 382:Condition members 'Locations.StateLocationId' have duplicate condition values. 错误3032:从第373行,第382行开始映射片段时出现问题:条件成员的Locations.StateLocationId'具有重复的条件值。

If i have a look at the CSDL, here is the association mapping for "CountyState" (a State has many counties, a County has 1 state): 如果我看一下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>

It's that Condition ColumnName="StateLocationId" which is complaining, because ZipCodeState association also this condition. 这是Condition ColumnName="StateLocationId" ,这是抱怨,因为ZipCodeState关联也是这个条件。

But i don't get it. 但我不明白。 The discriminators for all entities are unique (i have triple checked), and i would have thought this was a valid scenario: 所有实体的鉴别器都是唯一的(我有三重检查),我认为这是一个有效的场景:

  1. County has a single State, denoted by StateLocationId (Locations table) 县有一个州,由StateLocationId(Locations表)表示
  2. ZipCode has a single State, denoted by StateLocationId (Locations table) ZipCode有一个State,由StateLocationId(Locations表)表示

Is that not valid in TPH? 这在TPH中无效吗?

So i solved a few of my issues, but i hit a brick wall. 所以我解决了我的一些问题,但我碰到了一堵砖墙。

First of all, when you create self-referencing FK's in the database side, when you try and "Update Model from Database", Entity Framework will add these navigational properties to the main base type, as it has no explicit sense of TPH - you need to do this in the model side. 首先,当您在数据库端创建自引用FK时,当您尝试“从数据库更新模型”时,实体框架会将这些导航属性添加到主基类型,因为它没有明确的TPH感 - 您需要在模型方面做到这一点。

BUT, you can manually add the navigational properties to the child types. 但是,您可以手动将导航属性添加到子类型。

WRT this error: WRT此错误:

Error 3032: Problem in mapping fragments starting at lines 373, 382:Condition members 'Locations.StateLocationId' have duplicate condition values. 错误3032:从第373行,第382行开始映射片段时出现问题:条件成员的Locations.StateLocationId'具有重复的条件值。

That was because i had an FK called "Location_State" which i was attempting to use for the "ZipCode_State" relationship, AND the "City_State" relationship - which does not work (still no idea why). 那是因为我有一个名为“Location_State”的FK我试图用于“ZipCode_State”关系,以及“City_State”关系 - 这不起作用(仍然不知道为什么)。

So to solve that, i had to add extra columns and extra FK's - one called "ZipCode_State", and another called "City_State" - obviously it has to be a 1-1 between navs and physical FK's. 所以要解决这个问题,我必须添加额外的列和额外的FK - 一个叫做“ZipCode_State”,另一个称为“City_State” - 显然它必须是导航和物理FK之间的1-1。

Location.LocationType has no default value and is not nullable. Location.LocationType没有默认值,也不可为空。 A column value is required to store entity data. 存储实体数据需要列值。

That is my discriminator field. 那是我的鉴别领域。 In the database side, it is not nullable . 在数据库方面,它不可为空

I read threads about this issue, and they said you need to change the relationships from 0..* to 1..* - but my relationships already were 1..*. 我读了关于这个问题的线索,他们说你需要将关系从0 .. *更改为1 .. * - 但我的关系已经是1 .. *。

If you look at my "Locations" actual database table above, all the FK's are nullable (they have to be). 如果你查看我上面的“Locations”实际数据库表,所有FK都可以为空(它们必须是)。 Therefore i started wondering if my relationships should be 0..*. 因此我开始怀疑我的关系是否应为0 .. *。

But they are nullable because of the TPH - not all "Locations" will have a "State". 但由于TPH,它们可以为空 - 并非所有“地点”都有“国家”。 But if that Location is a "City", then it HAS to have a "State". 但如果该位置是“城市”,那么它就有了“国家”。

My feelings were further comforted by this SO question: ADO EF - Errors Mapping Associations between Derived Types in TPH 这个问题让我的感受更加安慰: ADO EF - 错误映射TPH中派生类型之间的关联

I was actually trying that workaround (before i even came across it), and the workaround does not work for me. 我实际上正在尝试这种解决方法(在我遇到它之前),并且解决方法对我不起作用。 I even tried changing all the relationships from 1..* to 0..*, and still no luck. 我甚至尝试将所有关系从1 .. *更改为0 .. *,但仍然没有运气。

Wasting too much time here, I've gone back to TPT. 在这里浪费了太多时间,我回到了TPT。

At the end of the day, with TPH i would have had a ridiculously large table, with lots and lots of redundant, nullable columns. 在一天结束时,使用TPH我会有一个可笑的大表,有很多冗余的可空列。 JOIN-wise, it's more efficient. 加入方式,效率更高。 But at least with TPT i am not required to have nullable and self-referencing FK's. 但至少对于TPT,我不需要有可空和自我引用的FK。

If anyone has a solution to this problem, let me know. 如果有人能解决这个问题,请告诉我。 But until then, im sticking with TPT. 但在那之前,我坚持使用TPT。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM