2011-08-11 14 views
5

Estoy tratando de esta clase:Uno a cero/uno la relación (Código primero)

public class Person 
{ 
    public int PersonID { get; set; } 
    public string Name { get; set; } 
    public int SpouseID { get; set; } 
    public virtual Person Spouse { get; set; } 
} 

La relación es la siguiente: Una persona ha uno o cero Cónyuge/ un cónyuge tiene una persona requerida

¿Es posible construir este modelo en la API Fluent?

Gracias.

Respuesta

6

Desafortunadamente, no es posible hacer una referencia personal de uno a uno porque en este momento EF no admite claves únicas. Para hacer que esta auto referencia real uno a uno SpouseID debe marcarse como único. EF permite uno a uno solo en claves primarias (la clave principal en la entidad dependiente debe ser también una clave externa para la entidad principal), lo que significa que la relación uno a uno terminará en PersonID <-> PersonID = dos entidades con el mismo PersonID en una sola tabla . No es posible porque PersonID es clave principal y debe ser único.

Puede manejarlo como uno-a-muchos y exponer única propiedad de desplazamiento individual como ustedes ya saben:

modelBuilder.Entity<Person>() 
      .HasOptional(p => p.Spouse) 
      .WithMany() 
      .HasForeingKey(s => s.SpouseID); 

Hacer cumplir uno-a-uno relación en la base de datos va a agregar custom database initializer y crear manualmente único índice en la columna SpouseID.

El problema es que es solo un modo de navegación para que pueda obtener el cónyuge de la persona, pero de ese Spouse no puede volver a su marido.

+0

Gracias por su ayuda Ladislav – Joao

1

Esta respuesta es sugerencia en lugar de una respuesta exacta.

En el mundo real, este no es el diseño correcto, en primer lugar, cada cónyuge tiene cónyuge que hace referencia a la misma persona, por ejemplo, el cónyuge del cónyuge de la persona es la persona misma. Hemos modelado esto en nuestra aplicación como Personas y PeronRelations, PersonRelations tienen propiedades FromPersonID, ToPersonID y Type. Tipo especifica "Marido < -> Wife", "esposa < -> marido", "Padre < -> Son", "Hijo < -> Padre", etc.

public class Person{ 
    public int PersonID {get;set;} 
    ... 
    public ICollection<PersonRelations> FromRelations {get;set;} 
    public ICollection<PersonRelations> ToRelations {get;set;} 

} 

public class PersonRelations{ 

    .. 
    public int FromPersonID {get;set;} 
    public int ToPersonID {get;set;} 

    public RelationType Type {get;set;} 
    public Person FromPerson {get;set;} 
    public Person ToPersion {get;set;} 

    // useful for Employment and Marriage 
    // durations 
    public DateTime? Start {get;set;} 
    public DateTime? End {get;set;} 
} 

public enum RelationType{ 
    Husband_Wife, 
    Wife_Husband, 
    Father_Son, 
    Son_Father, 
    Friend_Friend, 
    Employee_Employer, 
    Employer_Employee 
} 

Esto le da ventaja, ya que puede almacenar más información por relación y navegar en ambas direcciones junto con muchas consultas.

Cada relación tiene la relación opuesta correspondiente también. Y tendrá que escribir una lógica adicional para mantener una relación inversa adecuada también para que funcione correctamente.

Y esto es muy fácil de implementar en Entity Framework ya que es una relación simple de uno a muchos.

Cuestiones relacionadas