11

Sé que el trabajo de marco de entidades no le permite generar un modelo a partir de una base de datos usando claves únicas no primarias como una asociación de clave externa. ¿Puedo modificar el EDMX manualmente? Si es así, ¿alguien me puede dar un ejemplo o una referencia? Si no, ¿hay otras posibilidades?Entity Framework: solución alternativa al uso de claves únicas no primarias en una asociación

ejemplo más sencillo:

Aquí está el DDL para las tablas. Se dará cuenta de que tengo una clave externa de PersonType.TypeCode a 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] 

Aquí se genera la 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="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> 

me han tratado de modificar el EDMX para crear la navegación entre Propery personType y Person pero no han tenido éxito. Pensé que podría crear la asociación manualmente de alguna forma. Cualquier ayuda sería apreciada.

+0

Realmente no entiendo su esquema. Esto parece un '1-1' ¿verdad? Una 'Persona' tiene un' PersonType' en particular. Lo que no entiendo es por qué la tabla 'PersonType' tiene un campo llamado' PersonTypeId'. Si esta es una tabla de búsqueda, ¿no deberían tener 'TypeCode' (PK) y' TypeDesc'? Y luego el FK en 'Persona' a' TypeCode' funcionaría bien, ya que es un PK. – RPM1984

+0

@ RPM1984 .. El ejemplo es solo un ejemplo simple. No es algo que estoy usando, sino algo para mostrar el problema. Básicamente, el EF no le permitirá generar un modelo utilizando claves únicas no primarias. –

+0

Ok, pero creo que EF está haciendo lo correcto aquí. Aunque el campo es 'único', un FK debe hacer referencia a un PK, no a un Reino Unido. – RPM1984

Respuesta

12

Desafortunadamente, a partir de ahora no hay forma de definir una asociación en una clave candidata (es decir, PersonType.TypeCode). porque En EF (3.5 y 4.0) FK DEBE apuntar a las teclas principales.

De acuerdo con Alex James de his post here, esto es algo que el equipo EF está considerando para la próxima versión.

+12

Cuatro años más tarde, todavía no es compatible (( – AFD

+2

En serio, ¿cómo pueden las personas usar tripas "empresariales". El LinqToSQL abandonado (que es/fue mucho mejor ORM * start *) y EF1 lo hicieron mejor. EF 6.1 - aunque tal se prometió - todavía parece carecer de un principio RA * tan básico. – user2864740

+9

EF 6.1.2 (2015/02) aún no compatible :( –

Cuestiones relacionadas