Wiem, że praca frame entity nie pozwala na wygenerowanie modelu z bazy danych przy użyciu innych niż pierwotne kluczy unikalnych jako asocjacji klucza obcego. Czy mogę zmodyfikować EDMX ręcznie? Jeśli tak, czy ktoś może podać mi przykład lub referencję? Jeśli nie, czy są jakieś inne możliwości?Entity Framework: Alternatywne rozwiązanie do korzystania z kluczy innych niż pierwotne w powiązaniu
najprostszy przykład:
Oto DLL dla tabel. Można zauważyć, mam klucz obcy z PersonType.TypeCode do Person.TypeCode
CREATE TABLE [dbo].[PersonType](
[PersonTypeId] [int] NOT NULL,
[TypeCode] [varchar](10) NOT NULL,
[TypeDesc] [varchar](max) NULL,
CONSTRAINT [PK_PersonType] PRIMARY KEY CLUSTERED
([PersonTypeId] ASC)
CONSTRAINT [UK_PersonType] UNIQUE NONCLUSTERED
([TypeCode] ASC)
)
CREATE TABLE [dbo].[Person](
[PersonId] [int] NOT NULL,
[TypeCode] [varchar](10) NOT NULL,
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED
([PersonId] ASC)
)
ALTER TABLE [dbo].[Person] WITH CHECK ADD CONSTRAINT [FK_Person_PersonType] FOREIGN KEY([TypeCode])
REFERENCES [dbo].[PersonType] ([TypeCode])
ALTER TABLE [dbo].[Person] CHECK CONSTRAINT [FK_Person_PersonType]
Oto EDMX Wygenerowano
<?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="testModel.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">
<EntityContainer Name="testModelStoreContainer">
<EntitySet Name="Person" EntityType="testModel.Store.Person" store:Type="Tables" Schema="dbo" />
<EntitySet Name="PersonType" EntityType="testModel.Store.PersonType" store:Type="Tables" Schema="dbo" />
</EntityContainer>
<EntityType Name="Person">
<Key>
<PropertyRef Name="PersonId" />
</Key>
<Property Name="PersonId" Type="int" Nullable="false" />
<Property Name="TypeCode" Type="varchar" Nullable="false" MaxLength="10" />
</EntityType>
<!--Errors Found During Generation:
warning 6035: The relationship 'FK_Person_PersonType' has columns that are not part of the key of the table on the primary side of the relationship. The relationship was excluded.
-->
<EntityType Name="PersonType">
<Key>
<PropertyRef Name="PersonTypeId" />
</Key>
<Property Name="PersonTypeId" Type="int" Nullable="false" />
<Property Name="TypeCode" Type="varchar" Nullable="false" MaxLength="10" />
<Property Name="TypeDesc" Type="varchar(max)" />
</EntityType>
</Schema>
</edmx:StorageModels>
<!-- CSDL content -->
<edmx:ConceptualModels>
<Schema Namespace="testModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">
<EntityContainer Name="testEntities">
<EntitySet Name="People" EntityType="testModel.Person" />
<EntitySet Name="PersonTypes" EntityType="testModel.PersonType" />
</EntityContainer>
<EntityType Name="Person">
<Key>
<PropertyRef Name="PersonId" />
</Key>
<Property Name="PersonId" Type="Int32" Nullable="false" />
<Property Name="TypeCode" Type="String" Nullable="false" MaxLength="10" Unicode="false" FixedLength="false" />
</EntityType>
<EntityType Name="PersonType">
<Key>
<PropertyRef Name="PersonTypeId" />
</Key>
<Property Name="PersonTypeId" Type="Int32" Nullable="false" />
<Property Name="TypeCode" Type="String" Nullable="false" MaxLength="10" Unicode="false" FixedLength="false" />
<Property Name="TypeDesc" Type="String" MaxLength="Max" Unicode="false" FixedLength="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="testModelStoreContainer" CdmEntityContainer="testEntities">
<EntitySetMapping Name="People"><EntityTypeMapping TypeName="testModel.Person"><MappingFragment StoreEntitySet="Person">
<ScalarProperty Name="PersonId" ColumnName="PersonId" />
<ScalarProperty Name="TypeCode" ColumnName="TypeCode" />
</MappingFragment></EntityTypeMapping></EntitySetMapping>
<EntitySetMapping Name="PersonTypes"><EntityTypeMapping TypeName="testModel.PersonType"><MappingFragment StoreEntitySet="PersonType">
<ScalarProperty Name="PersonTypeId" ColumnName="PersonTypeId" />
<ScalarProperty Name="TypeCode" ColumnName="TypeCode" />
<ScalarProperty Name="TypeDesc" ColumnName="TypeDesc" />
</MappingFragment></EntityTypeMapping></EntitySetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
</edmx:Runtime>
Próbowałem zmodyfikować EDMX stworzyć propery nawigację pomiędzy personType i Person, ale nie udało się. Po prostu pomyślałem, że mogę utworzyć powiązanie ręcznie w jakiś sposób. Każda pomoc będzie doceniona.
Nie bardzo rozumiem twój schemat. To wygląda jak "1-1", prawda? "Osoba" ma określony "PersonType". Nie rozumiem, dlaczego tabela "PersonType" ma pole o nazwie "PersonTypeId". Jeśli jest to tabela odnośników, czy nie powinieneś mieć po prostu 'TypeCode' (PK) i' TypeDesc'? A następnie FK na 'Person' na' TypeCode' działałoby dobrze, ponieważ jest to PK. – RPM1984
@ RPM1984 .. Przykład to tylko prosty przykład. To nie jest coś, co używam, ale coś, co pokazuje problem. Zasadniczo EF nie pozwoli ci na wygenerowanie modelu przy użyciu specjalnych kluczy unikalnych. –
OK - ale myślę, że EF robi to, co należy. Mimo że pole jest "unikalne", FK powinno odnosić się do PK, a nie do Wielkiej Brytanii. – RPM1984