10

我目前使用Table Per Type(TPT)实现了一个实体框架4.0模型,但是有一些性能问题(大量的LOJ/CASE语句),以及两个特定域之间的问题映射(many-太多)。实体框架4每个层次的表 - 如何定义儿童的导航属性?

我决定尝试TPH。

我有一个名为“位置”,这是抽象的实体,以及所有其他实体的基础。

我再有 “国家”, “”, “国家”, “” 等所有的位置获得。

LocationType”是dicriminator

该部分工作正常,但我有问题试图定义派生类型的导航属性。

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

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

但是这需要所谓的“国家”上的导航性能“国家”派生实体。我该怎么做呢?当我生成数据库模型,我有一个表的所有FK的指向记录在同一个表:

alt text

(注:我在DB手动创建的FK的)。

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

我们如何做到这一点?

TPH也不清楚,如果我们可以先模型化,或者我们必须从数据库开始,修复模型然后重新生成数据库。我还没有在互联网上找到一个关于如何定义TPH儿童导航的好例子。

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

编辑

仍然没有解决 - 但是我尝试做模型的第一,做添加 - >新建关联,这确实在事实上让我一个导航添加到派生实体。但是当我尝试和“从模型生成数据库”时,它仍然尝试为“Location_Street”,“Location_Country”等创建表。这几乎就像TPH不能先模型一样。

编辑

这里是我当前的模型:

alt text

验证错误我目前得到:

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's。

编辑

所以我想通了上面的错误,那是因为我是缺少的连接表的邻居 - 拉链多对多。

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

但我现在收到此错误:

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

如果我有一个看看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协会还这个条件。

但我不明白。所有实体鉴别是唯一的(我有三重检查),我会认为这是一个有效的方案:

  1. 县拥有一个国家,由StateLocationId(位置表)表示
  2. 邮编有单状态,由StateLocationId(位置表)表示

这是否在TPH中无效?

+0

只是好奇:你有没有试过调整你的数据库,并坚持每种类型的表? – 2010-11-24 05:42:31

+0

@保罗凯斯特 - 表现只是*一个*的问题。我的域模型还包含“帖子”,其中有一个带有“位置”的M-M。对于TPT,由于每个位置都有自己的表格,因此将“Post”映射到许多“位置”非常困难。很难解释 - 但让我们说,如果我有一个单一的“地点”表,它会使协会更直接。 – RPM1984 2010-11-24 09:55:40

回答

4

所以我解决了我的一些问题,但我撞到了一堵砖墙。首先,当您在数据库端创建自引用FK时,当您尝试“从数据库更新模型”时,实体框架会将这些导航属性添加到主基类型,因为它没有明确的意义的TPH - 你需要在模型方面做到这一点。

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

WRT此错误:

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

那是因为我有一个FK称为“Location_State”我正在试图使用的“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 .. *。

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

但是它们是可空的,因为TPH - 并非所有的“地点”都会有一个“国家”。但是如果这个位置是一个“城市”,那么它必须有一个“国家”。

我的感情被这太问题进一步安慰:ADO EF - Errors Mapping Associations between Derived Types in TPH

我其实想的是解决办法(之前我甚至碰到它),以及解决方法不会为我工作。我甚至尝试将所有关系从1 .. *更改为0 .. *,但仍然没有运气。

浪费太多时间在这里,我回到了TPT。

在一天结束的时候,TPH会有一个可笑的大桌子,有很多很多冗余的可空列。联合方式,它更有效率。但至少在TPT中,我不需要有可空和自引用的FK。

如果有人解决了这个问题,请告诉我。但在那之前,我坚持使用TPT。