2012-02-24 21 views
30

tengo un modelo comoEntity Framework 4.3 código de primer múltiplo de muchos a muchos usando las mismas tablas

public class User 
{ 
    [Key] 
    public long UserId { get; set; } 

    [Required] 
    public String Nickname { get; set; } 

    public virtual ICollection<Town> Residencies { get; set; } 

    public virtual ICollection<Town> Mayorships { get; set; } 
} 

y

public class Town 
{ 
    [Key] 
    public long TownId { get; set; } 

    [Required] 
    public String Name { get; set; } 

    public virtual ICollection<User> Residents { get; set; } 
    public virtual ICollection<User> Mayors { get; set; } 
} 

Tenía la esperanza de EF crearía dos relaciones muchos a muchos usando crean automáticamente Tabla de TownResidents y TownMayors. Parece que no puedo encontrar la convención necesaria o la anotación explícita para obtener este resultado.

En su lugar obtengo dos FK UserIds en la tabla Town y dos FK TownIds en la tabla User.

¿Alguna idea de cómo lograr que EF vea estas dos relaciones muchas a muchas?

Gracias

Respuesta

30

Bueno, EF no tiene algún tipo de palabra y algoritmo de reconocimiento de la gramática que se requeriría para identificar que (probablemente) quiere que User.Residencies y Town.Residents forman un par de propiedades de navegación y User.Mayorships y Town.Mayors formar un segundo par Por lo tanto, se supone que tiene cuatro relaciones de uno a varios y que cada una de las cuatro propiedades de navegación pertenece a una de las relaciones. (Esta es la razón de las cuatro claves externas que ha visto en las tablas de la base.)

Esta suposición estándar no es lo que desea, por lo tanto, debe definir las relaciones explícitamente a anular esta convención estándar:

De cualquier con anotaciones de datos:

public class User 
{ 
    [Key] 
    public long UserId { get; set; } 

    [Required] 
    public String Nickname { get; set; } 

    [InverseProperty("Residents")] 
    public virtual ICollection<Town> Residencies { get; set; } 

    [InverseProperty("Mayors")] 
    public virtual ICollection<Town> Mayorships { get; set; } 
} 

O con API Fluido:

modelBuilder.Entity<User>() 
    .HasMany(u => u.Residencies) 
    .WithMany(t => t.Residents) 
    .Map(x => 
    { 
     x.MapLeftKey("UserId"); 
     x.MapRightKey("TownId"); 
     x.ToTable("TownResidents"); 
    }); 

modelBuilder.Entity<User>() 
    .HasMany(u => u.Mayorships) 
    .WithMany(t => t.Mayors) 
    .Map(x => 
    { 
     x.MapLeftKey("UserId"); 
     x.MapRightKey("TownId"); 
     x.ToTable("TownMayors"); 
    }); 

API Fluido tiene la ventaja de que se puede controlar el nam e de la tabla de enlaces (y los nombres de las columnas clave también). No puede definir esos nombres con anotaciones de datos.

+0

Gracias. Probé ambos métodos y ambos funcionaron, pero como dijiste, el Método fluido te permite controlar el nombre de la tabla, así que prefiero ese método. Gracias de nuevo. – Sean

+0

La parte del mapa no es necesaria. Su código api fluido hace el trabajo sin él. – ozgur

Cuestiones relacionadas