Multiple Inheritance with Entity Framework with TPH

青春壹個敷衍的年華 提交于 2019-12-23 04:09:45

问题


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.

I get the error:

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

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.

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>

回答1:


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.

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

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

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.

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.




回答2:


You seem to be trying to do table-per-hierarchy mapping (because I see only one table in your SSDL), but I don't see that you have set up a discriminator mapping in the CSDL. There should be a Condition node, like this:

            <Condition ColumnName="NotificationType" Value="Announcement"/>

In short, if you are trying to use a table per hierarchy mapping, you should review the instructions for configuring this and follow them, because you have not completed all of the steps.

If, on the other hand, you intend to do table per type mapping, then you seem to have missed a couple of tables when you updated from your database.



来源:https://stackoverflow.com/questions/2045924/multiple-inheritance-with-entity-framework-with-tph

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!