我决定尝试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的连接表.
但是现在我得到这个错误:
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.