c# – 实体框架4每层次表 – 如何定义儿童的导航属性?

前端之家收集整理的这篇文章主要介绍了c# – 实体框架4每层次表 – 如何定义儿童的导航属性?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我目前拥有一个具有Table Per Type(TPT)的实体框架4.0模型,但是有一些性能问题(很多LOJ / CASE语句),以及两个特定领域领域之间的问题映射(多对多)许多).

我决定尝试TPH.

我有一个称为“位置”的实体是抽象的,是所有其他实体的基础.

然后我有“国家”,“城市”,“国家”,“街”等都是从位置.

“LocationType”是双引号.

这部分工作正常,但是我有问题试图为派生类型定义导航属性.

例如,一个“国家”有一个“国家”,所以我应该可以做到这一点:

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

但这需要在“国家”衍生实体上称为“国家”的导航资产.我该怎么做?当我从数据库生成模型时,我有一个表,所有的FK指向同一个表中的记录:

(注意:我在DB中手动创建了这些FK).

但是,FK被放置在“位置”实体的导航,所以我如何将这些导航属性转移到派生实体?我无法复制粘贴导航,我不能“创建新的导航属性”,因为它不会让我定义开始/结束角色.

我们如何做到这一点?

如果我们可以先做模型,或者我们从DB开始,修正模型然后重新生成DB,那么TPH也不清楚.我还没有在互联网上找到一个很好的例子,说明如何在TPH上定义导航员.

注意:我不想做代码优先.我目前的解决方案具有TPT与EDMX和纯POCO,我希望不影响域模型/存储库(如果可能),只需更新EF模型/数据库.

编辑

仍然没有解决方案 – 但是我试图做模型第一,并做添加 – >新协会实际上允许我向导出的实体添加导航.但是当我尝试“从模型生成数据库”时,它仍然尝试为“Location_Street”,“Location_Country”等创建表.几乎像TPH不能先做模型.

编辑

这是我目前的模式:

验证错误我目前得到:

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).

只是想我会继续编辑这个问题与编辑关于我目前在哪里.我开始怀疑TPH与自引用FK是否可能.

编辑

所以我想出了上面的错误,那是因为我几乎没有邻居的ZipCode的连接表.

添加连接表(并将navs映射到该表)解决了上述错误.

但是现在我得到这个错误

Error 3032: Problem in mapping
fragments starting at lines 373,
382:Condition members
‘Locations.StateLocationId’ have
duplicate condition values.

如果我看CSDL,这里是“县州”的协会映射(一个州有很多县,县有1个州):

<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关联也是这个条件.

但我不明白所有实体的歧视者是唯一的(我已经三重检查),我认为这是一个有效的场景:

>县有一个状态,由StateLocationId(位置表)
> ZipCode有一个状态,由StateLocationId(Locations表)

是否在TPH无效?

解决方法

所以我解决了我的一些问题,但我打砖墙.

首先,当您在数据库端创建自引用FK时,当您尝试“从数据库更新模型”时,实体框架将这些导航属性添加到主基类型,因为它没有明确的TPH意义 – 您需要在模型方面做到这一点.

但是,您可以手动将导航属性添加到子类型.

WRT这个错误

Error 3032: Problem in mapping fragments starting at lines 373,382:Condition members ‘Locations.StateLocationId’ have duplicate condition values.

那是因为我有一个名为“Location_State”的FK,我试图使用“ZipCode_State”关系,并且“City_State”关系不起作用(仍然不知道为什么).

所以要解决这个问题,我不得不添加额外的列和额外的FK – 一个称为“ZipCode_State”,另一个称为“City_State” – 显然它必须是导航和物理FK之间的1-1.

Location.LocationType has no default value and is not nullable. A column value is required to store entity data.

那是我的鉴别器领域.在数据库端,它不可空.

我读了关于这个问题的线索,他们说你需要将关系从0 .. *更改为1 .. * – 但我的关系已经是1 .. *.

如果你看我上面的“地点”实际的数据库表,所有的FK都是可空的(它们必须是).所以我开始想知道我的关系应该是0 .. *.

但由于TPH,它们是无效的 – 并不是所有的“地点”都将具有“状态”.但是,如果这个位置是“城市”,那么它已经有了一个“国家”.

我的感觉进一步得到了这个SO问题的安慰:ADO EF – Errors Mapping Associations between Derived Types in TPH

我实际上正在尝试解决办法(在我甚至碰到它之前),解决方法对我来说并不奏效.我甚至尝试将所有关系从1 .. *改为0 .. *,仍然没有运气.

在这里浪费太多时间,我已经回到了TPT.

在最后,TPH我会有一个可笑的大桌子,有很多很多冗余,可空的列.加强智慧,更有效率.但是至少与TPT相比,我不需要具有可空的和自引用的FK.

如果有人解决这个问题,让我知道.但直到那时,我坚持TPT.

猜你在找的C#相关文章