Entity Framework 4 Table Per Hierarchy - 如何定义儿童的导航属性?
Posted
技术标签:
【中文标题】Entity Framework 4 Table Per Hierarchy - 如何定义儿童的导航属性?【英文标题】:Entity Framework 4 Table Per Hierarchy - How To Define Navigational Properties On Children? 【发布时间】:2010-11-24 04:47:47 【问题描述】:我目前有一个 Entity Framework 4.0 模型和每个类型的表 (TPT),但存在一些性能问题(许多 LOJ/CASE 语句),以及两个特定领域领域之间的问题映射(许多对多)。
我决定试试 TPH。
我有一个名为“Location”的实体抽象,是所有其他实体的基础。
然后我有“Country”、“City”、“State”、“Street”,等都来自位置。
“LocationType”是鉴别符。
这部分工作正常,但我在尝试为派生类型定义导航属性时遇到问题。
例如,一个“State”只有一个“Country”,所以我应该可以这样做:
var state = _ctx.Locations.OfType<State>().Include("Country").First();
var countryForState = state.Country;
但这需要在“State”派生实体上具有一个名为“Country”的导航属性。我该怎么做呢?当我从数据库生成模型时,我有一个表,所有 FK 都指向同一个表中的记录:
(注意:我在数据库中手动创建了这些 FK)。
但是 FK 被放置为“Location”实体上的导航,那么我如何将这些导航属性向下移动到派生实体?我无法复制+粘贴导航,也无法“创建新的导航属性”,因为它不允许我定义开始/结束角色。
我们如何做到这一点?
TPH 也不清楚我们是否可以先做模型,或者我们必须从数据库开始,修复模型然后重新生成数据库。我还没有在互联网上找到一个很好的例子来说明如何为患有 TPH 的儿童定义导航。
注意:我不想先做代码。我当前的解决方案有 EDMX 和纯 POCO 的 TPT,我希望不影响域模型/存储库(如果可能),并且只更新 EF 模型/数据库。
编辑
仍然没有解决方案-但是我尝试先执行模型,然后执行添加-> 新关联,这实际上允许我向派生实体添加导航。但是当我尝试“从模型生成数据库”时,它仍然尝试为“Location_Street”、“Location_Country”等创建表。这几乎就像 TPH 不能先做模型一样。
编辑
这是我目前的模型:
我目前得到的验证错误:
错误 1 错误 3002:映射问题 从行开始的片段 359:潜在的运行时违规 表位置的键 (Locations.LocationId):列 (Locations.LocationId) 映射到 EntitySet Neighbourhood邮政编码的 特性 (NeighbourhoodZipCode.Neighbourhood.LocationId) 在概念方面,但他们没有 形成 EntitySet 的关键属性 (NeighbourhoodZipCode.Neighbourhood.LocationId, NeighbourhoodZipCode.ZipCode.LocationId)。
只是想我会继续编辑这个问题,并编辑关于我目前所处的位置。我开始怀疑带有自引用 FK 的 TPH 是否可能。
编辑
所以我发现了上述错误,那是因为我错过了 Neighbourhood-ZipCode 多对多的连接表。
添加连接表(并将导航映射到该表)解决了上述错误。
但现在我得到了这个错误:
错误 3032:映射问题 从第 373 行开始的片段, 382:条件成员 'Locations.StateLocationId' 有 重复条件值。
如果我查看 CSDL,这里是“CountyState”的关联映射(一个州有很多县,一个县有 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(位置表)表示
这在 TPH 中无效吗?
【问题讨论】:
只是好奇:您是否尝试过调整数据库并坚持使用每种类型的表? @Paul Keister - 性能只是问题中的一个。我的域模型还包括“帖子”,它有一个带有“位置”的 M-M。使用 TPT,因为每个位置都有自己的表,所以很难将“帖子”映射到多个“位置”。很难解释 - 但如果我有 1 个单一的“位置”表,它会让关联更加直接。 我也刚刚尝试为 EF 抱怨的重复关系添加额外的 FK - 例如 FK_County_State 和 FK_ZipCode_State 而不是 FK_State 由两者共享),然后重建模型 - 仍然是完全相同的错误。不要告诉我我也必须创建额外的实际列? (现在试试) RE 我上面的评论 - 是的,我也必须创建那些实际的附加列。这解决了上述错误 - 现在我当然有下一个。 :) @Alex James - 如果您在那里,您能否告知是否有解决此问题的方法? (见我下面的答案)。否则我将不得不坚持 TPT。 【参考方案1】:所以我解决了一些问题,但我碰壁了。
首先,当您在数据库端创建自引用 FK 时,当您尝试“从数据库更新模型”时,Entity Framework 会将这些导航属性添加到主基类型,因为它没有明确的意义TPH - 您需要在模型端执行此操作。
但是,您可以手动将导航属性添加到子类型。
WRT 这个错误:
错误 3032:从第 373、382 行开始映射片段时出现问题:条件成员“Locations.StateLocationId”具有重复的条件值。
那是因为我有一个名为“Location_State”的 FK,我试图将它用于“ZipCode_State”关系和“City_State”关系 - 这不起作用(仍然不知道为什么)。
所以为了解决这个问题,我不得不添加额外的列和额外的 FK——一个称为“ZipCode_State”,另一个称为“City_State”——显然它必须是 navs 和物理 FK 之间的 1-1。
Location.LocationType 没有默认值并且不能为空。存储实体数据需要列值。
这是我的鉴别器字段。在数据库端,它是不可为空的。
我阅读了有关此问题的线程,他们说您需要将关系从 0..* 更改为 1..* - 但我的关系已经是 1..*。
如果您查看我上面的“位置”实际数据库表,所有 FK 都可以为空(它们必须是)。因此我开始怀疑我的关系是否应该是 0..*.
但由于 TPH,它们可以为空 - 并非所有“位置”都有“状态”。但是如果那个位置是一个“城市”,那么它必须有一个“州”。
这个 SO 问题进一步安慰了我的感受:ADO EF - Errors Mapping Associations between Derived Types in TPH
我实际上是在尝试这种解决方法(在我遇到它之前),但这种解决方法对我不起作用。我什至尝试将所有关系从 1..* 更改为 0..*,但仍然没有运气。
在这里浪费了太多时间,我已经回到 TPT。
在一天结束时,如果使用 TPH,我将拥有一张大得离谱的表,其中包含大量冗余、可为空的列。 JOIN-wise,它更有效。但至少对于 TPT,我不需要具有可为空和自引用的 FK。
如果有人对此问题有解决方案,请告诉我。但在那之前,我坚持使用 TPT。
【讨论】:
+1 目前,我有一些具有 TPT 继承的模型,我考虑使用 TPH 重新构建模型。现在我知道这将是浪费时间。 是的,目前我有一个包含 10 个可空 FK 的表。看起来真的很丑。 JOINS 会表现得更好吗?可能是物理意义上的,但不是逻辑意义上的。select * from tablea inner join table b
(TPT) 和 select * from tablea as one inner join tablea as two
(TPH) 之间唯一真正的区别是 TPH 转到同一个表,TPT 转到另一个表。 JOIN 操作的成本是相同的(我认为)。我主要担心的是我没有看到这么多可为空的 FK 的意义以上是关于Entity Framework 4 Table Per Hierarchy - 如何定义儿童的导航属性?的主要内容,如果未能解决你的问题,请参考以下文章
Entity Framework Code-First(9.7):DataAnnotations - Table Attribute
Query Using Entity Framework Error with Database Table name Error
Entity Framework 6 - ORA-00932 同时加入 ToString