Множественное наследование с Entity Framework с TPH

В дополнение к этому вопросу: Entity Framework TPH с множественным абстрактным наследованием и VS .2008 sp1 .net 3.5 С#

Я решил добавить организации и школу. Организация (абстрактно) наследует от Партии, а Школа (конкретно) наследует от Организации.

Я получаю сообщение об ошибке:

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

Я видел много ошибок 3034 во время своих путешествий в EF. Но обычно они относятся к навигационным свойствам. Я не видел таких ошибок в наследовании.

Вот мой 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>

person itchi    schedule 12.01.2010    source источник
comment
Изменить. Добавлены условные сопоставления в соответствии с рекомендацией Крейга Стунца. Ошибки все еще сохраняются.   -  person itchi    schedule 13.01.2010


Ответы (2)


Я знаю, что этот вопрос устарел, но я потратил много времени на изучение подобной проблемы в недавнем приключении с EF 5.0 (и 6.0.0-beta1) и эта статья привела меня к действительному решению. Спасибо автору.

У меня есть сложная иерархия, отображаемая с использованием TPH:

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

Где полужирный указывает на абстракцию, а курсив указывает на дополнительные сопоставления, специфичные для этого класса (и подклассов) в ту же таблицу (конечно).

В основном решение состояло в том, чтобы создать 4 столбца дискриминатора в таблице и сопоставить каждый уровень в иерархии с другим столбцом дискриминатора. Обратите внимание, что абстрактные классы на уровне B и ниже также должны быть сопоставлены и иметь указанное значение дискриминатора.

На это потрачено много времени, все примеры и документация TPH, кажется, охватывают только основы. В реальном мире все может быть немного сложнее!

Надеюсь, это поможет кому-то.

person SteveChapman    schedule 07.08.2013

Кажется, вы пытаетесь выполнить сопоставление таблиц и иерархий (потому что я вижу только одну таблицу в вашем SSDL), но я не вижу, чтобы вы настроили сопоставление дискриминатора в CSDL. Должен быть узел Condition, например:

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

Короче говоря, если вы пытаетесь использовать сопоставление таблиц для каждой иерархии, вам следует просмотреть инструкции по настройке и следовать им, поскольку вы не выполнили все шаги.

Если, с другой стороны, вы намереваетесь выполнить сопоставление таблиц по типам, то вы, похоже, пропустили пару таблиц при обновлении из своей базы данных.

person Craig Stuntz    schedule 12.01.2010
comment
Я делаю TPH, см. заголовок и теги. Я также успешно сделал много наследств A-›B-›C. Что уникально в этом, так это то, что я делаю A-›B-›C и A-›D-›E, где A,B,D являются абстрактными. Мне еще предстоит найти статью/руководство/сообщение в блоге, где это пытались сделать. Я установил условия, но все равно получаю ту же ошибку (я обновил edmx выше, чтобы отразить это) - person itchi; 13.01.2010
comment
Мы сделали TPH с A->B и A->C, где A является абстрактным, что, безусловно, работает. Начните с этого и попытайтесь вырастить его. - person Craig Stuntz; 13.01.2010
comment
Да, у меня много A-›B и A-›C. У меня также есть A-›B и A-›C-›D, где A и C являются статическими, что также работает. Но в тот момент, когда я увеличиваю его до A-›B-›C и A-›D-›E, он терпит неудачу, как указано выше. - person itchi; 13.01.2010
comment
У меня похожие проблемы - у меня A-›B, A-›C-›D, A-›C-›E. A и C — абстрактные, а B, D, E — конкретные (с дискриминаторами). Мне кажется, ему не нравится, когда один и тот же дискриминатор "перерезает" ветви наследования. - person Lee Atkinson; 30.04.2010