c# entity-framework ef-code-first entity-framework-4.3

c# - El código de Entity Framework 4.3 primero multiplica muchos a muchos usando las mismas tablas



entity-framework ef-code-first (1)

Tengo un modelo como

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; } }

Esperaba que EF creara de dos a muchas relaciones utilizando la tabla TownResidents y TownMayors creada automáticamente. Parece que no puedo encontrar la convención o anotación explícita necesaria para obtener este resultado.

En su lugar, estoy obteniendo dos FK UserIds en la tabla Ciudad y dos FK TownIds en la tabla Usuario.

¿Alguna idea de cómo obtener EF para ver estas relaciones de dos a muchas?

Gracias


Bueno, EF no tiene algún tipo de algoritmo de reconocimiento de palabras y gramática que se requeriría para identificar que usted (probablemente) desea que las User.Residencies y Town.Residents formen un par de propiedades de navegación y que los User.Mayorships y Town.Mayors User.Mayorships y la Town.Mayors un segundo par. Por lo tanto, se supone que tiene cuatro relaciones de uno a muchos y que cada una de las cuatro propiedades de navegación pertenece a una de las relaciones. (Este es el motivo de las cuatro claves externas que ha visto en las tablas de la base de datos).

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

Ya sea 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 Fluent API:

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

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