使用TPH的实体框架进行多重继承 [英] Multiple Inheritance with Entity Framework with TPH

查看:83
本文介绍了使用TPH的实体框架进行多重继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

此问题的进一步内容:
具有多个抽象的实体框架TPH 和VS.2008 sp1 .net 3.5 c#

Further to this question: Entity Framework TPH with multiple abstract inheritance and VS.2008 sp1 .net 3.5 c#

我决定添加组织和学校。组织(抽象)从组织继承,学校(混凝土)从组织继承。

I decided to add Organizations and a School. Organization(abstract) inherits from Party, and School(concrete) inherits from Organization.

我得到了错误:

Error   1   Error 3034: Problem in Mapping Fragments starting at lines 73, 93: Two entities with different keys are mapped to the same row. Ensure these two mapping fragments do not map two groups of entities with different keys to the same group of rows.
    C:\Users\xxx\Documents\Visual Studio 2008\Projects\TEST\TEST\Model1.edmx    74  29  TEST

我在EF旅途中看到了3034个错误。但通常它们与导航属性有关。我没有在继承中看到这样的错误。

I've seen the 3034 errors alot along my travels in EF. But typically they relate to navigational properties. I haven't seen errors like this in inheritence.

这是我的edmx xml:

Here's my edmx xml:

<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="1.0"
xmlns:edmx="http://schemas.microsoft.com/ado/2007/06/edmx">
    <!-- EF Runtime content -->
    <edmx:Runtime>
        <!-- SSDL content -->
        <edmx:StorageModels>
            <Schema Namespace="test_1Model.Store" Alias="Self"
          Provider="System.Data.SqlClient" ProviderManifestToken="2005"
          xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"
          xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
                <EntityContainer Name="test_1ModelStoreContainer">
                    <EntitySet Name="Student" EntityType="test_1Model.Store.Student"
              store:Type="Tables" Schema="dbo" />
                </EntityContainer>
                <EntityType Name="Student">
                    <Key>
                        <PropertyRef Name="Id" />
                    </Key>
                    <Property Name="Id" Type="int" Nullable="false"
              StoreGeneratedPattern="Identity" />
                    <Property Name="PartyInfo" Type="varchar(max)" Nullable="false" />
                    <Property Name="PersonInfo" Type="varchar(max)" Nullable="true" />
                    <Property Name="StudInfo" Type="varchar(max)" Nullable="true" />
                    <Property Name="OrgInfo" Type="varchar(max)" Nullable="true" />
                    <Property Name="SchoolInfo" Type="varchar(max)" Nullable="true" />
                    <Property Name="TypeOfParty" Type="varchar(max)" Nullable="false" />
                </EntityType>
            </Schema>
        </edmx:StorageModels>
        <!-- CSDL content -->
        <edmx:ConceptualModels>
            <Schema Namespace="test_1Model" Alias="Self"
          xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
                <EntityContainer Name="test_Entities">
                    <EntitySet Name="PartySet" EntityType="test_1Model.Party" />
                </EntityContainer>
                <EntityType Name="Party" Abstract="true">
                    <Key>
                        <PropertyRef Name="Id" />
                    </Key>
                    <Property Name="Id" Type="Int32" Nullable="false" />
                    <Property Name="PartyInfo" Type="String" Nullable="false"
              MaxLength="Max" Unicode="false" FixedLength="false" />
                </EntityType>
                <EntityType Name="Person" BaseType="test_1Model.Party" Abstract="true" >
                    <Property Name="PersonInfo" Type="String" Nullable="false" />
                </EntityType>
                <EntityType Name="Student" BaseType="test_1Model.Person" >
                    <Property Name="StudInfo" Type="String" Nullable="false" />
                </EntityType>
                <EntityType Name="Organization" BaseType="test_1Model.Party" Abstract="true" >
                    <Property Name="OrgInfo" Type="String" Nullable="false" />
                </EntityType>
                <EntityType Name="School" BaseType="test_1Model.Organization" >
                    <Property Name="SchoolInfo" Type="String" Nullable="false" />
                </EntityType>
            </Schema>
        </edmx:ConceptualModels>
        <!-- C-S mapping content -->
        <edmx:Mappings>
            <Mapping Space="C-S"
          xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">
                <EntityContainerMapping
            StorageEntityContainer="test_1ModelStoreContainer"
            CdmEntityContainer="test_Entities">
                    <EntitySetMapping Name="PartySet">
                        <EntityTypeMapping TypeName="IsTypeOf(test_1Model.Party)">
                            <MappingFragment StoreEntitySet="Student">
                                <ScalarProperty Name="PartyInfo" ColumnName="PartyInfo" />
                                <ScalarProperty Name="Id" ColumnName="Id" />
                            </MappingFragment>
                        </EntityTypeMapping>
                        <EntityTypeMapping TypeName="IsTypeOf(test_1Model.Person)">
                            <MappingFragment StoreEntitySet="Student">
                                <ScalarProperty Name="Id" ColumnName="Id" />
                                <ScalarProperty Name="PersonInfo" ColumnName="PersonInfo" />
                            </MappingFragment>
                        </EntityTypeMapping>
                        <EntityTypeMapping TypeName="test_1Model.Student">
                            <MappingFragment StoreEntitySet="Student">
                                <ScalarProperty Name="Id" ColumnName="Id" />
                                <ScalarProperty Name="StudInfo" ColumnName="StudInfo" />
                                <ScalarProperty Name="PersonInfo" ColumnName="PersonInfo" />
                                <ScalarProperty Name="PartyInfo" ColumnName="PartyInfo" />
                                <Condition ColumnName="TypeOfParty" Value="STUDENT" />
                            </MappingFragment>
                        </EntityTypeMapping>
                        <EntityTypeMapping TypeName="IsTypeOf(test_1Model.Organization)">
                            <MappingFragment StoreEntitySet="Student">
                                <ScalarProperty Name="Id" ColumnName="Id" />
                                <ScalarProperty Name="OrgInfo" ColumnName="OrgInfo" />
                            </MappingFragment>
                        </EntityTypeMapping>
                        <EntityTypeMapping TypeName="test_1Model.School">
                            <MappingFragment StoreEntitySet="Student">
                                <ScalarProperty Name="Id" ColumnName="Id" />
                                <ScalarProperty Name="OrgInfo" ColumnName="OrgInfo" />
                                <ScalarProperty Name="PartyInfo" ColumnName="PartyInfo" />
                                <ScalarProperty Name="SchoolInfo" ColumnName="SchoolInfo" />
                                <Condition ColumnName="TypeOfParty" Value="SCHOOL" />
                            </MappingFragment>
                        </EntityTypeMapping>
                    </EntitySetMapping>
                </EntityContainerMapping>
            </Mapping>
        </edmx:Mappings>
    </edmx:Runtime>
    <!-- EF Designer content (DO NOT EDIT MANUALLY BELOW HERE) -->
    <edmx:Designer xmlns="http://schemas.microsoft.com/ado/2007/06/edmx">
        <edmx:Connection>
            <DesignerInfoPropertySet>
                <DesignerProperty Name="MetadataArtifactProcessing"
        Value="EmbedInOutputAssembly" />
            </DesignerInfoPropertySet>
        </edmx:Connection>
        <edmx:Options>
            <DesignerInfoPropertySet>
                <DesignerProperty Name="ValidateOnBuild" Value="true" />
            </DesignerInfoPropertySet>
        </edmx:Options>
        <!-- Diagram content (shape and connector positions) -->
        <edmx:Diagrams>
            <Diagram Name="SqlServer_Model" >
                <EntityTypeShape EntityType="test_1Model.Party" Width="1.5" PointX="1.25" PointY="3.25" Height="1.4033821614583326" />
                <InheritanceConnector EntityType="test_1Model.Person" ManuallyRouted="false">
                    <ConnectorPoint PointX="2" PointY="4.6533821614583326" />
                    <ConnectorPoint PointX="2" PointY="5.75" />
                </InheritanceConnector>
                <EntityTypeShape EntityType="test_1Model.Organization" Width="1.5" PointX="3.875" PointY="5.625" Height="1.2110807291666665" />
                <InheritanceConnector EntityType="test_1Model.Organization">
                    <ConnectorPoint PointX="2.75" PointY="3.9516910807291663" />
                    <ConnectorPoint PointX="4.625" PointY="3.9516910807291663" />
                    <ConnectorPoint PointX="4.625" PointY="5.625" />
                </InheritanceConnector>
                <EntityTypeShape EntityType="test_1Model.School" Width="1.5" PointX="3.875" PointY="7.875" Height="1.2110807291666657" />
                <InheritanceConnector EntityType="test_1Model.School">
                    <ConnectorPoint PointX="4.625" PointY="6.8360807291666665" />
                    <ConnectorPoint PointX="4.625" PointY="7.875" />
                </InheritanceConnector>
            </Diagram>
        </edmx:Diagrams>
    </edmx:Designer>
</edmx:Edmx>


推荐答案

我知道这个问题已经很久了,但是我花了长期研究EF 5.0(和6.0.0-beta1)以及这篇文章使我找到了有效的解决方案。感谢作者。

I know this question is ages old, but I spent a long time researching a similar problem in a recent adventure with EF 5.0 (and 6.0.0-beta1), and this article led me to a valid solution. Thanks to the author.

我使用TPH映射了一个复杂的层次结构:

I have a complex hierarchy mapped using TPH:


  • A1 - B1 -C1

  • A1 - B1 -C2

  • A1 - B2 -C3

  • A1 - B2 -C4

  • A1 - B2 -C5

  • A1 - B2 - C6 - D1 -E1

  • A1 - B2 - C6 - D1 -E2

  • A1 - B2 - C6 - D1 -E3

  • A1 - B2 - C6 - D2 -E4

  • A1 - B2 - C6 - D2 -E5

  • A1 - B2 - C6 - D2 -E6

  • A1 - B2 - C6 - D3 -E7

  • A1 - B2 - C6 - D3 -E8

  • A1 - B2 - C6 - D3 -E9

  • A1 - B1 - C1
  • A1 - B1 - C2
  • A1 - B2 - C3
  • A1 - B2 - C4
  • A1 - B2 - C5
  • A1 - B2 - C6 - D1 - E1
  • A1 - B2 - C6 - D1 - E2
  • A1 - B2 - C6 - D1 - E3
  • A1 - B2 - C6 - D2 - E4
  • A1 - B2 - C6 - D2 - E5
  • A1 - B2 - C6 - D2 - E6
  • A1 - B2 - C6 - D3 - E7
  • A1 - B2 - C6 - D3 - E8
  • A1 - B2 - C6 - D3 - E9

粗体表示抽象,而斜体表示特定于该类(和子类)的同一表(当然)的其他映射。

Where bold indicates abstract, and italic indicates additional mappings specific to that class (and subclasses) to the same table (of course).

基本上,解决方案是要在表格中创建4个区分列,并映射每个列层次结构中的el到另一个区分符列。请注意,B级及以下的抽象类也需要映射并指定一个鉴别值。

Basically the solution was to create 4 discriminator columns in the table, and map each level in the hierarchy to a different discriminator column. Note that the abstract classes in level B and below also need to be mapped and have a discriminator value specified.

为此,所有示例和文档都浪费了很多时间。 TPH的内容似乎仅涵盖基础知识。在现实世界中,事情可能会变得更加复杂!

A lot of time wasted on this, all the examples and documentation of TPH seem to only cover the basics. In the real world things can get a little more complex!

希望这对某人有所帮助。

Hope this helps someone.

这篇关于使用TPH的实体框架进行多重继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆