Código EF primero - Relación opcional 1 a 1

Quiero mapear una relación opcional 1 a 1 en una base de datos existente con EF Code First.

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?

Esto es lo que he intentado 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);

Obtengo la 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 *.

preguntado el 16 de mayo de 11 a las 17:05

1 Respuestas

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"));

Establece solo sus objetos de navegación en sus POCO y, en su lugar, usa una API fluida para asignar su clave a la columna correcta.

contestado el 17 de mayo de 11 a las 02:05

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 API fluida de relación o las anotaciones de datos. - David C

Le recomiendo que incluya la propiedad de clave externa según la convención (msdn.microsoft.com/en-us/data/jj679962). Si siempre que crea relaciones entre entidades, hágalo a través de esta propiedad clave en lugar de la propiedad de la entidad. Descubrí que de esta manera es menos probable que obtenga ciertas excepciones, como claves duplicadas en el administrador de estado del objeto y excepciones más significativas cuando las actualizaciones salen mal. - MIP1983

¿Cómo puedo usar TAMBIÉN un ContactId campo en User? Si utilizo el código anterior y defino un ContactId campo en Usuario me da un error diciendo que es una propiedad duplicada. ¿Cómo puedo decirle al marco de la entidad que la columna está definida con MapKey y el ContactId definidos en Usuario son los mismos. - gyozo kudor

Hola @gyozokudor, ¿encontraste una manera de tener el campo ContactId también? Gracias. - richard lo que sea

Usaría un FK ContactId. Mira aquí: entityframeworktutorial.net/code-first/… - Blaise

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.