2012-03-21 16 views
11

Estoy utilizando el marco de entidad y el modelado de una relación muchos a muchos.¿Es posible hacer referencia directa a una tabla de muchos a muchos utilizando el marco de entidades, primero el código

He creado la relación entre las dos entidades que utilizan la API de fluidez (digamos usuarios y grupos):

this.HasMany(t => t.Users) 
.WithMany(t => t.Groups) 
.Map(
m => 
{ 
    m.ToTable("GroupMembers"); 
    m.MapLeftKey("Group_Id"); 
    m.MapRightKey("User_Id"); 
}); 

Esto funciona muy bien, pero me gustaría también poder hacer referencia a la tabla GroupMembers directamente. Para hacer eso, tengo algo como:

[Table("GroupMembers")] 
public class GroupMember 
{ 
    #region Properties 

    /// <summary> 
    /// Gets or sets the group. 
    /// </summary> 
    public virtual Group Group { get; set; } 

    /// <summary> 
    /// Gets or sets the Id of rht group. 
    /// </summary> 
    [Key] 
    [Column("Group_Id", Order = 1)] 
    public int GroupId { get; set; } 

    /// <summary> 
    /// Gets or sets the user. 
    /// </summary> 
    public virtual User User { get; set; } 

    /// <summary> 
    /// Gets or sets the Id of the user. 
    /// </summary> 
    [Key] 
    [Column("User_Id", Order = 2)] 
    public int UserId { get; set; } 

    #endregion 
}  

Sin embargo, voy a tener el siguiente error durante la inicialización del DbContext:

esquema especificado no es válido. Errores: (381,6): error 0019: EntitySet 'GroupUser' con esquema 'dbo' y tabla 'GroupMembers' era ya definido. Cada EntitySet debe hacer referencia a un esquema exclusivo y a la tabla .

Creo que esto se debe a que el marco de entidad no se da cuenta de que la tabla GroupMembers especificada en la API fluida y la tabla de entidades GroupMembers son en realidad una en la misma. En otras palabras, si elimino el código API fluido que describe la relación muchos a muchos, entonces puedo inicializar el DbContext.

¿Puedo tener una tabla de muchos a muchos a la que también puedo hacer referencia directamente?

Respuesta

11

No, no puedes. Si desea tener acceso a la tabla de unión a través de una entidad separada debe reemplazar sus muchos-a-muchos relación por dos relaciones de uno a muchos y cambiar las propiedades de navegación en User y Group para referirse a GroupMember:

public class Group 
{ 
    public int GroupId { get; set; } 
    public virtual ICollection<GroupMember> Members { get; set; } 
} 

public class User 
{ 
    public int UserId { get; set; } 
    public virtual ICollection<GroupMember> Members { get; set; } 
} 

modelBuilder.Entity<Group>() 
    .HasMany(g => g.Members) 
    .WithRequired(gm => gm.Group); 

modelBuilder.Entity<User>() 
    .HasMany(u => u.Members) 
    .WithRequired(gm => gm.User); 

¿Por qué quiere esta entidad GroupMember? No contiene ningún significado comercial y solo tiene referencias y claves. Por lo general, puede obtener y modificar cualquier contenido de la tabla de unión escribiendo consultas LINQ y utilizando los DbSets/entities Group y User y sus propiedades de navegación.

+1

Gracias. Tanto el Usuario como el Grupo heredan de una tabla base, Principal, y hay otra tabla, Permisos, que contiene permisos para usuarios y grupos. La consulta LINQ para eso se parece a: desde p en contexto.Permisos unir m en context.GroupMembers en p.PrincipalId es igual a m.GroupId donde m.UserId.Equals (principalId) seleccionar p No estoy muy seguro de cómo realizar esa consulta sin hacer referencia directa a la tabla GroupMembers. – Eric

+0

@Eric: recomendaría crear una pregunta separada para esto con más detalles sobre el modelo. – Slauma

+0

@Eric Tengo absolutamente el mismo problema, parece ilógico que una API fluida solo pueda crear entidades en lugar de usar las ya existentes – Lu4

0

Sí, puedes! Compruebe this hacia fuera. Además, elimine la entidad GroupMembers y la colección IDbSet.

+0

Esto no responde la pregunta, sino todo lo contrario. Se trata de cómo hacer que sea automático * sin * acceso a la tabla, la pregunta era sobre cómo acceder a la tabla. –

0

Lo solucionamos creando una vista que solo se usa para definir la relación. Teníamos otros campos en la tabla de búsqueda a los que necesitábamos acceder.

La vista simplemente selecciona los campos de unión de la tabla de búsqueda.

1

Sí, puede ... Si utiliza otro contexto. Si intenta mapear más de una entidad a la misma tabla en el mismo Contexto, obtendrá el error. Pero si coloca las dos asignaciones en Contextos separados, entonces no habrá problemas. De esta forma, puede tener una asignación que describa una relación muchos-muchos con la tabla de unión transparente como si solo hubiera claves externas en ella ... Y puede tener otra asignación, con su propio contexto, para exponer la tabla de unión real si quieres conocer las propiedades de la relación.

Cuestiones relacionadas