好的,这个问题已经解决了。
从概念上讲,我有一个可以拥有许多子资源和许多父资源的资源实体。 Resource表有两个字段,ID和Name,ID是主键。
为了完成多对多的关系,我创建了一个ResourceHierarchy表,它有两个字段(Parent_ID,Child_ID)和两个外键,每个字段引用Resource表(ID)的主键,ResourceHierarchy表有一个复合词主键(Parent_ID,Child_ID)
现在我们已经知道每个资源可以作为父资源或子资源充当其他资源,但从逻辑上讲,并非所有资源都会拥有父资源,但除了这一点之外。举个例子,假设我的资源表中有以下资源。
ID Name
10000 Little House
10001 Font Door
10002 Roof
10003 Roof Tile
10004 Tile Monster
在ResourceHierarchy表中,我们有以下关系。
Parent_ID Child_ID
10000 10001
10000 10002
10002 10003
10004 10003
然后实体框架生成实体,到目前为止一直很好......
如果要检查edmx文件中生成的代码,您会看到ResourceHierarchy表被视为关系,而ResourceHierarchy表无法通过代码访问,因为它不被视为实体。
如果这就是我想要的,那么它将完美无缺。
但是,当我想将数量列添加到资源实体层次结构时,问题就开始了。例如,小房子只有一个前门和一个屋顶,但屋顶和瓷砖怪物资源可以有很多屋顶瓦片。
因此,如果我们将一个Quantity列添加到Resource表中,那么我们得到以下内容。
ID Name Quantity
10000 Little House 1
10001 Font Door 1
10002 Roof 1
10003 Roof Tile 5
10004 Tile Monster 1
这就产生了屋顶和瓷砖怪物必须共享5个屋顶瓦片的问题。所以我自然会尝试将quantity列添加到ResourceHierarchy表中,但是只要我这样做并刷新生成的代码,现在将ResourceHierarchy表视为实体而不是之前的关系。现在,为了回到资源表,我必须经历这个非概念性的“实体/关系”,这不是很直接。这就像我的概念模型中有一个Entity,它只用于遍历资源实体,我甚至不确定Resource.Children.Add(r)是否会在db的ResourceHierarchy表中创建新行。这就像我将从一个我只用作关系的实体中挑选出属性,即数量。
理想情况下,ResourceHierarchy表的Quantity列看起来像这样。
Parent_ID Child_ID Quantity
10000 10001 1
10000 10002 1
10002 10003 8
10004 10003 13
并且资源实体仍然具有子项,父项导航属性,并以某种方式访问“数量”列作为资源实体的属性。
我尝试合并生成的代码,从拥有数量列而不是数量列但抛出异常,我将其解释为ResourceHierarchy表可以是关系或实体,但不是两者。
请帮助!
edmx在db中的ResourceHierarchy表中添加和排除quantity列时发生了巨大变化。
以下是一个示例比较,唯一的区别是Resource是ResourceType,ResourceHierarchy是ResourceTypeHierarchy。
SSDL存储模型除了ResourceTypeHierarchy EntityType中的一个额外属性外没有任何更改,所以我不会在下面包含它。
没有关于资源等级的数量列
RESOURCETYPEHIERARCHY是一种关系
<!-- CSDL content -->
<edmx:ConceptualModels>
<Schema Namespace="MyModel" Alias="Self" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2008/09/edm">
<EntityContainer Name="MyEntities">
<EntitySet Name="ResourceTypes" EntityType="MyModel.ResourceType" />
<AssociationSet Name="ResourceTypeHierarchy" Association="MyModel.ResourceTypeHierarchy">
<End Role="ResourceType" EntitySet="ResourceTypes" />
<End Role="ResourceType1" EntitySet="ResourceTypes" /></AssociationSet></EntityContainer>
<EntityType Name="ResourceType">
<Key>
<PropertyRef Name="ID" /></Key>
<Property Type="Int32" Name="ID" Nullable="false" />
<Property Type="String" Name="Type" Nullable="false" MaxLength="25" FixedLength="false" Unicode="false" />
<NavigationProperty Name="Parents" Relationship="MyModel.ResourceTypeHierarchy" FromRole="ResourceType" ToRole="ResourceType1" />
<NavigationProperty Name="Children" Relationship="MyModel.ResourceTypeHierarchy" FromRole="ResourceType1" ToRole="ResourceType" /></EntityType>
<Association Name="ResourceTypeHierarchy">
<End Type="MyModel.ResourceType" Role="ResourceType" Multiplicity="*" />
<End Type="MyModel.ResourceType" Role="ResourceType1" Multiplicity="*" /></Association></Schema>
</edmx:ConceptualModels>
<!-- C-S mapping content -->
<edmx:Mappings>
<Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs">
<EntityContainerMapping StorageEntityContainer="MyModelStoreContainer" CdmEntityContainer="MyEntities">
<EntitySetMapping Name="ResourceTypes">
<EntityTypeMapping TypeName="IsTypeOf(MyModel.ResourceType)">
<MappingFragment StoreEntitySet="ResourceType">
<ScalarProperty Name="ID" ColumnName="ID" />
<ScalarProperty Name="Type" ColumnName="Type" /></MappingFragment></EntityTypeMapping></EntitySetMapping>
<AssociationSetMapping Name="ResourceTypeHierarchy" TypeName="MyModel.ResourceTypeHierarchy" StoreEntitySet="ResourceTypeHierarchy">
<EndProperty Name="ResourceType1">
<ScalarProperty Name="ID" ColumnName="Parent_ID" /></EndProperty>
<EndProperty Name="ResourceType">
<ScalarProperty Name="ID" ColumnName="Child_ID" /></EndProperty></AssociationSetMapping></EntityContainerMapping>
</Mapping>
</edmx:Mappings>
在资源层面上有数量列
RESOURCETYPEHIERARCHY现在是一个实体
<!-- C-S mapping content -->
<edmx:Mappings>
<Mapping Space="C-S" xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs">
<EntityContainerMapping StorageEntityContainer="MyModelStoreContainer" CdmEntityContainer="MyEntities">
<EntitySetMapping Name="ResourceTypes">
<EntityTypeMapping TypeName="IsTypeOf(MyModel.ResourceType)">
<MappingFragment StoreEntitySet="ResourceType">
<ScalarProperty Name="ID" ColumnName="ID" />
<ScalarProperty Name="Type" ColumnName="Type" /></MappingFragment></EntityTypeMapping></EntitySetMapping>
<EntitySetMapping Name="ResourceTypeHierarchies">
<EntityTypeMapping TypeName="IsTypeOf(MyModel.ResourceTypeHierarchy)">
<MappingFragment StoreEntitySet="ResourceTypeHierarchy">
<ScalarProperty Name="Child_ID" ColumnName="Child_ID" />
<ScalarProperty Name="Parent_ID" ColumnName="Parent_ID" />
<ScalarProperty Name="Quantity" ColumnName="Quantity" /></MappingFragment></EntityTypeMapping></EntitySetMapping>
<AssociationSetMapping Name="FK_Child" TypeName="MyModel.FK_Child" StoreEntitySet="ResourceTypeHierarchy">
<EndProperty Name="ResourceTypeHierarchy">
<ScalarProperty Name="Child_ID" ColumnName="Child_ID" />
<ScalarProperty Name="Parent_ID" ColumnName="Parent_ID" /></EndProperty>
<EndProperty Name="ResourceType">
<ScalarProperty Name="ID" ColumnName="Child_ID" /></EndProperty></AssociationSetMapping>
<AssociationSetMapping Name="FK_Parent" TypeName="MyModel.FK_Parent" StoreEntitySet="ResourceTypeHierarchy">
<EndProperty Name="ResourceTypeHierarchy">
<ScalarProperty Name="Child_ID" ColumnName="Child_ID" />
<ScalarProperty Name="Parent_ID" ColumnName="Parent_ID" /></EndProperty>
<EndProperty Name="ResourceType">
<ScalarProperty Name="ID" ColumnName="Parent_ID" /></EndProperty></AssociationSetMapping></EntityContainerMapping>
</Mapping>
</edmx:Mappings>
答案 0 :(得分:1)
我相信这是有道理的。我的意思是,如果你把一个属性放在一个建立两个实体之间关系的表上,那么该表必须(至少从数据表示理论)表示为一个合适的实体。如果仔细考虑一下,你会理解为什么。您提到的数量是关系的属性,而不是任何相关实体的属性。因此,必须将表视为实体而不是关系。
现在关于如何克服这个问题,我想到的一件事(虽然我不确定这是否会完全解决你的问题)是按照你原先的想法处理关系(没有数量)并且有另一张表(将映射到您模型中的实体),用于存储特定关系的数量。我认为这个表甚至可以对你的db到原始关系表有一个外键约束,虽然这个外键不能映射到模型上的关系(因为你没有端点的实体),但这仍然是允许您在存储上保持数据完整性。
希望这有帮助, 维克托•