2011-05-16 22 views
26

Quiero mapear una relación opcional de 1 a 1 en una base de datos existente con EF Code First.Código EF Primero - Relación opcional de 1 a 1

esquema simple:

User 
Username 
ContactID 

Contact 
ID 
Name 

Obviamente ContactID se une a Contact.ID. El campo ContactID es anulable, por lo que la relación es opcional: 0 o 1, nunca muchos.

Entonces, ¿cómo especifico esta relación en EF Code First, con este esquema existente?

Aquí es lo que he probado hasta ahora:

public class User 
{ 
    [Key] 
    public string Username { get; set; } 
    public int? ContactID { get; set; } 

    [ForeignKey("ContactID")] 
    public virtual Contact Contact { get; set; } 
} 

public class Contact 
{ 
    [Key] 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual User User { get; set; } 
} 

modelBuilder.Entity<User>().HasOptional<Contact>(u=> u.Contact) 
    .WithOptionalDependent(c => c.User); 

me sale el siguiente excepción:

System.Data.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 
'User_Contact_Source' in relationship 'User_Contact'. Because the Dependent 
Role properties are not the key properties, the upper bound of the multiplicity 
of the Dependent Role must be *. 

Respuesta

42

Una solución sería;

public class User 
{ 
    [Key] 
    public string Username { get; set; } 

    public virtual Contact Contact { get; set; } 
} 

public class Contact 
{ 
    [Key] 
    public int ID { get; set; } 
    public string Name { get; set; } 

    public virtual User User { get; set; } 
} 

     modelBuilder.Entity<User>() 
      .HasOptional<Contact>(u => u.Contact) 
      .WithOptionalDependent(c => c.User).Map(p => p.MapKey("ContactID")); 

sólo se ha establecido sus objetos de navegación en su POCOs y en su lugar se usan API fluida para mapear su clave a la columna correcta.

+0

Esto me ayudó a resolver lo siguiente al intentar configurar un 0: 1 a 0: 1 - El extremo principal de esta asociación debe configurarse explícitamente utilizando la relación API o anotaciones de datos con fluidez. –

+1

Le recomiendo que incluya la propiedad clave externa según la convención (https://msdn.microsoft.com/en-us/data/jj679962). Si cada vez que crea relaciones entre entidades, hágalo a través de esta propiedad clave en lugar de la propiedad de la entidad. He descubierto que es menos probable que obtengas ciertas excepciones, como duplicar claves en el administrador de estados de objetos y excepciones más significativas cuando las actualizaciones fallan. – MIP1983

+9

¿Cómo puedo usar TAMBIÉN un campo 'ContactId' en' User'? Si utilizo el código anterior y defino un campo 'ContactId' en Usuario, me da un error al decir que es una propiedad duplicada. ¿Cómo puedo decirle a la estructura de la entidad que la columna definida con 'MapKey' y la' ContactId' definida en User son las mismas. –

Cuestiones relacionadas