11

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.

+0

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

+0

@ 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. –

+0

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

Odpowiedz

12

Niestety od tej pory nie można zdefiniować powiązania na kluczu kandydującym (tj. PersonType.TypeCode). ponieważ W EF (3.5 i 4.0) FK MUSZĄ wskazywać na Klucze podstawowe.
Zgodnie z Alex James z his post here, jest to coś, co zespół EF rozważa dla następnej wersji.

+12

Cztery lata później wciąż nie jest obsługiwany (( – AFD

+2

) Poważnie, w jaki sposób ludzie mogą używać takich flaków "korporacyjnych": opuszczony LinqToSQL (który jest/był znacznie lepszy ORM * start *) i EF1 był lepszy EF 6.1 - mimo że zostało obiecane - wciąż wydaje się brakować takiej * podstawowej * zasady RA. – user2864740

+9

EF 6.1.2 (2015/02) nadal nie jest wspierany :( –

Powiązane problemy