Фон
Я пишу библиотеку доступа к данным с использованием ADO Entity Framework в Visual Studio 2008 SP1 с использованием .NET Framework 3.5 SP1. Я пытаюсь создать ассоциации между двумя объектами, которые оба являются производными от абстрактного типа. Я представляю обе иерархии наследования сущностей, используя Таблица на иерархию (TPH), что означает, что есть только две таблицы - по одной для каждой иерархии наследования сущностей.
ПРИМЕЧАНИЕ Вы можете использовать Таблицу по типу (TPT), чтобы избежать этой проблемы, но у нее есть свои недостатки. См. здесь и здесь для получения дополнительной информации при выборе между моделями сохранения наследования.
Вот снимок экрана конструктора Entity Model:
А вот скриншот схемы базы данных:
Предположения
Когда вы создаете ассоциации в ADO Entity Framework Designer между производными типами, смоделированными с помощью TPH с использованием Visual Studio 2008 SP1 и .NET Framework 3.5 с пакетом обновления 1 (SP1), вы, вероятно, получите следующее сообщение об ошибке «Ошибка 3034: сопоставлены два объекта с разными ключами» в одну и ту же строку. Убедитесь, что эти два фрагмента сопоставления не отображают две группы сущностей с перекрывающимися ключами на одну и ту же группу строк. "
Исходя из того, что у меня есть , читать онлайн , чтобы решить эту проблему, вы должны добавить условие для связи с внешним ключом следующим образом:
<Condition ColumnName="Endpoint1" IsNull="false" />
Вот снимок экрана этой правки для ассоциации PersonPersonToPerson1:
Ограничения
- Базовые классы каждой иерархии (т. Е. Node и Link) должны быть абстрактными.
- Свойства навигации из ассоциаций между двумя производными типами должны различаться по типу ссылки (например, PersonToPerson и PersonToLocation). Это означает, что вы не можете создавать ассоциации между абстрактными базовыми классами Link и Node.
Проблема:
Когда я создаю Модель сущности, как описано выше, и добавляю Условия в AssociationMappings, как описано в Допущениях выше, я получаю «Ошибка 3023» при построении / проверке модели.
Error 1 Error 3023: Problem in Mapping Fragments starting at lines 146, 153, 159, 186, 195, 204, 213: Column Link.Endpoint1 has no default value and is not nullable. A column value is required to store entity data.
An Entity with Key (PK) will not round-trip when:
((PK is NOT in 'LinkSet' EntitySet OR PK does NOT play Role 'PersonToPerson' in AssociationSet 'PersonPersonToPerson1') AND (PK is in 'LinkSet' EntitySet OR PK plays Role 'PersonToPerson' in AssociationSet 'PersonPersonToPerson1' OR PK plays Role 'PersonToPerson' in AssociationSet 'PersonPersonToPerson'))
C:\Documents and Settings\Demo\My Documents\Visual Studio 2008\Projects\GraphExample2.BusinessEntities\GraphExample2.BusinessEntities\GraphModel.edmx 147 15 GraphExample2.BusinessEntities
В Entity Framework зацикливается на описанном выше сценарии то, что два свойства сопоставляются с одним и тем же внешним ключом. Например, столбец и внешний ключ для Endpoint1 сопоставляются со свойством Person в производном типе PersonToLocation и сопоставляются со свойством Leader в производном типе PersonToPerson.
Я не понимаю, почему это проблема. Поскольку свойства Leader / Follower находятся только в производном типе PersonToPerson, а не в любом другом производном типе или базовом типе, и то же самое относится и к свойству Person / Location, почему поля TypeDiscriminator недостаточно для EF, чтобы выяснить, какой установить данный ряд принадлежит?
Мне кажется, что если вы имеете дело с объектом, где TypeDiscriminator = 1, вы помещаете Endpoint1 в Leader и Endpoint2 в Follower. Аналогично, если вы имеете дело с объектом, где TypeDiscriminator = 2, вы помещаете конечную точку 1 в Person и конечную точку 2 в Location.
Вопрос:
Как разрешить ошибку 3023, чтобы эти ассоциации произошли?
OR
Как создать тип связей в ADO Entity Framework, который я описал выше?
Ссылки:
Код
SQL:
USE [GraphExample2]
GO
/****** Object: Table [dbo].[Node] Script Date: 02/17/2009 14:36:13 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Node](
[NodeID] [int] NOT NULL,
[NodeTypeDiscriminator] [int] NOT NULL,
[Name] [varchar](255) NOT NULL,
[Description] [varchar](1023) NULL,
CONSTRAINT [PK_Node] PRIMARY KEY CLUSTERED
(
[NodeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: Table [dbo].[Link] Script Date: 02/17/2009 14:36:12 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Link](
[LinkID] [int] NOT NULL,
[LinkTypeDiscriminator] [int] NOT NULL,
[Endpoint1] [int] NOT NULL,
[Endpoint2] [int] NOT NULL,
[Name] [varchar](255) NULL,
[Description] [varchar](1023) NULL,
CONSTRAINT [PK_Link] PRIMARY KEY CLUSTERED
(
[LinkID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
/****** Object: ForeignKey [FK_Link_Node_Endpoint1] Script Date: 02/17/2009 14:36:12 ******/
ALTER TABLE [dbo].[Link] WITH CHECK ADD CONSTRAINT [FK_Link_Node_Endpoint1] FOREIGN KEY([Endpoint1])
REFERENCES [dbo].[Node] ([NodeID])
GO
ALTER TABLE [dbo].[Link] CHECK CONSTRAINT [FK_Link_Node_Endpoint1]
GO
/****** Object: ForeignKey [FK_Link_Node_Endpoint2] Script Date: 02/17/2009 14:36:12 ******/
ALTER TABLE [dbo].[Link] WITH CHECK ADD CONSTRAINT [FK_Link_Node_Endpoint2] FOREIGN KEY([Endpoint2])
REFERENCES [dbo].[Node] ([NodeID])
GO
ALTER TABLE [dbo].[Link] CHECK CONSTRAINT [FK_Link_Node_Endpoint2]
GO
EDMX:
<?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="GraphModel.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="GraphModelStoreContainer">
<EntitySet Name="Link" EntityType="GraphModel.Store.Link" store:Type="Tables" Schema="dbo" />
<EntitySet Name="Node" EntityType="GraphModel.Store.Node" store:Type="Tables" Schema="dbo" />
<AssociationSet Name="FK_Link_Node_Endpoint1" Association="GraphModel.Store.FK_Link_Node_Endpoint1">
<End Role="Node" EntitySet="Node" />
<End Role="Link" EntitySet="Link" />
</AssociationSet>
<AssociationSet Name="FK_Link_Node_Endpoint2" Association="GraphModel.Store.FK_Link_Node_Endpoint2">
<End Role="Node" EntitySet="Node" />
<End Role="Link" EntitySet="Link" />
</AssociationSet>
</EntityContainer>
<EntityType Name="Link">
<Key>
<PropertyRef Name="LinkID" />
</Key>
<Property Name="LinkID" Type="int" Nullable="false" />
<Property Name="LinkTypeDiscriminator" Type="int" Nullable="false" />
<Property Name="Endpoint1" Type="int" Nullable="false" />
<Property Name="Endpoint2" Type="int" Nullable="false" />
<Property Name="Name" Type="varchar" MaxLength="255" />
<Property Name="Description" Type="varchar" MaxLength="1023" />
</EntityType>
<EntityType Name="Node">
<Key>
<PropertyRef Name="NodeID" />
</Key>
<Property Name="NodeID" Type="int" Nullable="false" />
<Property Name="NodeTypeDiscriminator" Type="int" Nullable="false" />
<Property Name="Name" Type="varchar" Nullable="false" MaxLength="255" />
<Property Name="Description" Type="varchar" MaxLength="1023" />
</EntityType>
<Association Name="FK_Link_Node_Endpoint1">
<End Role="Node" Type="GraphModel.Store.Node" Multiplicity="1" />
<End Role="Link" Type="GraphModel.Store.Link" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Node">
<PropertyRef Name="NodeID" />
</Principal>
<Dependent Role="Link">
<PropertyRef Name="Endpoint1" />
</Dependent>
</ReferentialConstraint>
</Association>
<Association Name="FK_Link_Node_Endpoint2">
<End Role="Node" Type="GraphModel.Store.Node" Multiplicity="1" />
<End Role="Link" Type="GraphModel.Store.Link" Multiplicity="*" />
<ReferentialConstraint>
<Principal Role="Node">
<PropertyRef Name="NodeID" />
</Principal>
<Dependent Role="Link">
<PropertyRef Name="Endpoint2" />
</Dependent>
</ReferentialConstraint>
</Association>
</Schema>
</edmx:StorageModels>
<!-- CSDL content -->
<edmx:ConceptualModels>
<Schema xmlns="http://schemas.microsoft.com/ado/2006/04/edm" Namespace="GraphModel" Alias="Self">
<EntityContainer Name="GraphModelContainer" >
<EntitySet Name="NodeSet" EntityType="GraphModel.Node" />
<EntitySet Name="LinkSet" EntityType="GraphModel.Link" />
<AssociationSet Name="PersonPersonToPerson" Association="GraphModel.PersonPersonToPerson">
<End Role="Person" EntitySet="NodeSet" />
<End Role="PersonToPerson" EntitySet="LinkSet" />
</AssociationSet>
<AssociationSet Name="PersonPersonToPerson1" Association="GraphModel.PersonPersonToPerson1">
<End Role="Person" EntitySet="NodeSet" />
<End Role="PersonToPerson" EntitySet="LinkSet" />
</AssociationSet>
<AssociationSet Name="Person_PersonToLocation" Association="GraphModel.Person_PersonToLocation">
<End Role="Person" EntitySet="NodeSet" />
<End Role="PersonToLocation" EntitySet="LinkSet" />
</AssociationSet>
<AssociationSet Name="Location_PersonToLocation" Association="GraphModel.Location_PersonToLocation">
<End Role="Location" EntitySet="NodeSet" />
<End Role="PersonToLocation" EntitySet="LinkSet" />
</AssociationSet>
</EntityContainer>
<EntityType Name="Node" Abstract="true">
<Key>
<PropertyRef Name="NodeId" />
</Key>
<Property Name="NodeId" Type="Int32" Nullable="false" />
<Property Name="Name" Type="String" Nullable="false" />
<Property Name="Description" Type="String" Nullable="true" />
</EntityType>
<EntityType Name="Person" BaseType="GraphModel.Node" >
<NavigationProperty Name="Leaders" Relationship="GraphModel.PersonPersonToPerson" FromRole="Person" ToRole="PersonToPerson" />
<NavigationProperty Name="Followers" Relationship="GraphModel.PersonPersonToPerson1" FromRole="Person" ToRole="PersonToPerson" />
<NavigationProperty Name="Locations" Relationship="GraphModel.Person_PersonToLocation" FromRole="Person" ToRole="PersonToLocation" />
</EntityType>
<EntityType Name="Location" BaseType="GraphModel.Node" >
<NavigationProperty Name="Visitors" Relationship="GraphModel.Location_PersonToLocation" FromRole="Location" ToRole="PersonToLocation" />
</EntityType>
<EntityType Name="Link" Abstract="true">
<Key>
<PropertyRef Name="LinkId" />
</Key>
<Property Name="LinkId" Type="Int32" Nullable="false" />
<Property Name="Name" Type="String" Nullable="true" />
<Property Name="Description" Type="String" Nullable="true" />
</EntityType>
<EntityType Name="PersonToPerson" BaseType="GraphModel.Link" >
<NavigationProperty Name="Leader" Relationship="GraphModel.PersonPersonToPerson" FromRole="PersonToPerson" ToRole="Person" />
<NavigationProperty Name="Follower" Relationship="GraphModel.PersonPersonToPerson1" FromRole="PersonToPerson" ToRole="Person" />
</EntityType>
<EntityType Name="PersonToLocation" BaseType="GraphModel.Link" >
<NavigationProperty Name="Person" Relationship="GraphModel.Person_PersonToLocation" FromRole="PersonToLocation" ToRole="Person" />
<NavigationProperty Name="Location" Relationship="GraphModel.Location_PersonToLocation" FromRole="PersonToLocation" ToRole="Location" />
</EntityType>
<Association Name="PersonPersonToPerson">
<End Type="GraphModel.Person" Role="Person" Multiplicity="1" />
<End Type="GraphModel.PersonToPerson" Role="PersonToPerson" Multiplicity="*" />
</Association>
<Association Name="PersonPersonToPerson1">
<End Type="GraphModel.Person" Role="Person" Multiplicity="1" />
<End Type="GraphModel.PersonToPerson" Role="PersonToPerson" Multiplicity="*" />
</Association>
<Association Name="Person_PersonToLocation">
<End Type="GraphModel.Person" Role="Person" Multiplicity="1" />
<End Type="GraphModel.PersonToLocation" Role="PersonToLocation" Multiplicity="*" />
</Association>
<Association Name="Location_PersonToLocation">
<End Type="GraphModel.Location" Role="Location" Multiplicity="1" />
<End Type="GraphModel.PersonToLocation" Role="PersonToLocation" Multiplicity="*" />
</Association>
</Schema>
</edmx:ConceptualModels>
<!-- C-S mapping content -->
<edmx:Mappings>
<Mapping xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS" Space="C-S">
<Alias Key="Model" Value="GraphModel" />
<Alias Key="Target" Value="GraphModel.Store" />
<EntityContainerMapping CdmEntityContainer="GraphModelContainer" StorageEntityContainer="GraphModelStoreContainer">
<EntitySetMapping Name="LinkSet">
<EntityTypeMapping TypeName="IsTypeOf(GraphModel.Link)">
<MappingFragment StoreEntitySet="Link">
<ScalarProperty Name="Description" ColumnName="Description" />
<ScalarProperty Name="Name" ColumnName="Name" />
<ScalarProperty Name="LinkId" ColumnName="LinkID" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(GraphModel.PersonToPerson)">
<MappingFragment StoreEntitySet="Link" >
<ScalarProperty Name="LinkId" ColumnName="LinkID" />
<Condition ColumnName="LinkTypeDiscriminator" Value="1" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(GraphModel.PersonToLocation)">
<MappingFragment StoreEntitySet="Link" >
<ScalarProperty Name="LinkId" ColumnName="LinkID" />
<Condition ColumnName="LinkTypeDiscriminator" Value="2" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<EntitySetMapping Name="NodeSet">
<EntityTypeMapping TypeName="IsTypeOf(GraphModel.Node)">
<MappingFragment StoreEntitySet="Node">
<ScalarProperty Name="Description" ColumnName="Description" />
<ScalarProperty Name="Name" ColumnName="Name" />
<ScalarProperty Name="NodeId" ColumnName="NodeID" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(GraphModel.Person)">
<MappingFragment StoreEntitySet="Node" >
<ScalarProperty Name="NodeId" ColumnName="NodeID" />
<Condition ColumnName="NodeTypeDiscriminator" Value="1" />
</MappingFragment>
</EntityTypeMapping>
<EntityTypeMapping TypeName="IsTypeOf(GraphModel.Location)">
<MappingFragment StoreEntitySet="Node" >
<ScalarProperty Name="NodeId" ColumnName="NodeID" />
<Condition ColumnName="NodeTypeDiscriminator" Value="2" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
<AssociationSetMapping Name="PersonPersonToPerson1" TypeName="GraphModel.PersonPersonToPerson1" StoreEntitySet="Link">
<EndProperty Name="Person">
<ScalarProperty Name="NodeId" ColumnName="Endpoint1" />
</EndProperty>
<EndProperty Name="PersonToPerson">
<ScalarProperty Name="LinkId" ColumnName="LinkID" />
</EndProperty>
<Condition ColumnName="Endpoint1" IsNull="false" />
</AssociationSetMapping>
<AssociationSetMapping Name="PersonPersonToPerson" TypeName="GraphModel.PersonPersonToPerson" StoreEntitySet="Link">
<EndProperty Name="Person">
<ScalarProperty Name="NodeId" ColumnName="Endpoint2" />
</EndProperty>
<EndProperty Name="PersonToPerson">
<ScalarProperty Name="LinkId" ColumnName="LinkID" />
</EndProperty>
<Condition ColumnName="Endpoint2" IsNull="false" />
</AssociationSetMapping>
<AssociationSetMapping Name="Person_PersonToLocation" TypeName="GraphModel.Person_PersonToLocation" StoreEntitySet="Link">
<EndProperty Name="Person">
<ScalarProperty Name="NodeId" ColumnName="Endpoint1" />
</EndProperty>
<EndProperty Name="PersonToLocation">
<ScalarProperty Name="LinkId" ColumnName="LinkID" />
</EndProperty>
<Condition ColumnName="Endpoint1" IsNull="false" />
</AssociationSetMapping>
<AssociationSetMapping Name="Location_PersonToLocation" TypeName="GraphModel.Location_PersonToLocation" StoreEntitySet="Link">
<EndProperty Name="Location">
<ScalarProperty Name="NodeId" ColumnName="Endpoint2" />
</EndProperty>
<EndProperty Name="PersonToLocation">
<ScalarProperty Name="LinkId" ColumnName="LinkID" />
</EndProperty>
<Condition ColumnName="Endpoint2" IsNull="false" />
</AssociationSetMapping>
</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="GraphModel" ZoomLevel="114" >
<EntityTypeShape EntityType="GraphModel.Node" Width="1.5" PointX="5.875" PointY="1.375" Height="1.427958984375" />
<EntityTypeShape EntityType="GraphModel.Person" Width="1.5" PointX="5.875" PointY="3.25" Height="1.4279589843749996" />
<EntityTypeShape EntityType="GraphModel.Location" Width="1.5" PointX="7.75" PointY="4.625" Height="1.0992643229166665" />
<InheritanceConnector EntityType="GraphModel.Location">
<ConnectorPoint PointX="7.375" PointY="2.0889794921875" />
<ConnectorPoint PointX="8.5" PointY="2.0889794921875" />
<ConnectorPoint PointX="8.5" PointY="4.625" />
</InheritanceConnector>
<EntityTypeShape EntityType="GraphModel.Link" Width="1.5" PointX="2.875" PointY="1.375" Height="1.427958984375" />
<EntityTypeShape EntityType="GraphModel.PersonToPerson" Width="1.75" PointX="2.625" PointY="3.125" Height="0.9349169921875" />
<InheritanceConnector EntityType="GraphModel.PersonToPerson">
<ConnectorPoint PointX="3.625" PointY="2.802958984375" />
<ConnectorPoint PointX="3.625" PointY="3.125" />
</InheritanceConnector>
<InheritanceConnector EntityType="GraphModel.Person">
<ConnectorPoint PointX="6.625" PointY="2.802958984375" />
<ConnectorPoint PointX="6.625" PointY="3.25" />
</InheritanceConnector>
<EntityTypeShape EntityType="GraphModel.PersonToLocation" Width="1.875" PointX="0.75" PointY="4.625" Height="1.2636116536458326" />
<InheritanceConnector EntityType="GraphModel.PersonToLocation">
<ConnectorPoint PointX="2.875" PointY="2.0889794921875" />
<ConnectorPoint PointX="1.65625" PointY="2.0889794921875" />
<ConnectorPoint PointX="1.65625" PointY="4.625" />
</InheritanceConnector>
<AssociationConnector Association="GraphModel.PersonPersonToPerson">
<ConnectorPoint PointX="5.875" PointY="3.8193058268229163" />
<ConnectorPoint PointX="4.375" PointY="3.8193058268229163" />
</AssociationConnector>
<AssociationConnector Association="GraphModel.PersonPersonToPerson1">
<ConnectorPoint PointX="5.875" PointY="3.4721529134114579" />
<ConnectorPoint PointX="4.375" PointY="3.4721529134114579" />
</AssociationConnector>
<AssociationConnector Association="GraphModel.Person_PersonToLocation">
<ConnectorPoint PointX="6.625" PointY="4.677958984375" />
<ConnectorPoint PointX="6.625" PointY="5.1875" />
<ConnectorPoint PointX="2.625" PointY="5.1875" />
</AssociationConnector>
<AssociationConnector Association="GraphModel.Location_PersonToLocation">
<ConnectorPoint PointX="7.75" PointY="5.4791666666666661" />
<ConnectorPoint PointX="2.625" PointY="5.4791666666666661" />
</AssociationConnector>
</Diagram>
</edmx:Diagrams>
</edmx:Designer>
</edmx:Edmx>