自定义类Identity / Entity Framework多对多关系

时间:2016-03-06 20:38:41

标签: c# entity-framework many-to-many asp.net-identity

我在c#中使用Entity Framework,Asp.net Identity和MVC来创建我的网站。

尝试实施“群组”功能我一直面临着一个问题...... 我实现了休闲(基于此:Create code first, many to many, with additional fields in association table):

public class ApplicationUser : IdentityUser
{

    [...]

    public virtual List<Group> Groups { get; set; }
}

并且:

public class Group
{
    public int GroupID { get; set; }
    [Required]
    [StringLength(100, MinimumLength = 2)]
    public string Name { get; set; }

    public virtual List<ApplicationUser> Members { get; set; }
}

带有额外属性(状态)的链接类:

public class ApplicationUserGroup
{
    [Key, Column(Order = 0)]
    public string ApplicationUserId { get; set; }
    [Key, Column(Order = 1)]
    public int GroupId { get; set; }

    public virtual ApplicationUser ApplicationUser { get; set;}
    public virtual Group Group { get; set; }

    // 1 : simple member
    // 2 : administrator
    public int Status { get; set; }

    public ApplicationUserGroup()
    {
        Status = 1;
    }
}

我设法将我的表作为ApplicationUserGroups进入我的数据库,但实体继续生成另一个没有我的状态字段的表GroupApplicationUsers ...

我相信问题来自身份,有人帮我吗?

PS:对不起我的英文,我是法国人^^

1 个答案:

答案 0 :(得分:2)

您需要使用适当的属性装饰您的实体属性,或使用流畅的api让EF了解您要执行的操作。因此,在DbContext课程中使用流畅的api,您应该覆盖OnModelCreating方法。然后使用以下代码:

protected override void OnModelCreating(DbModelBuilder mb)
{
    mb.Entity<ApplicationUser>()
        .HasMany(au => au.Groups)
        .WithMany(grp => grp.Members)
        .Map(m =>
        {
            m.ToTable("ApplicationUserGroup");
            m.MapLeftKey("ApplicationUserId");
            m.MapRightKey("GroupId");
        });
}

这告诉EF使用您的ApplicationUserGroup实体/表作为多对多关系的联结表。

编辑。根据您提供的链接,只有让EF将连接表本身作为隐藏表处理时,上述解决方案才有效。你不能在你的模型中拥有它。因此,正确的解决方案是在连接表中使用两个一对多关系,在这种情况下,模型中可以存在这种关系。

首先更改您的实体类,如下所示:

public class ApplicationUser : IdentityUser
{

    [...]

    public virtual List<ApplicationUserGroup> UserGroups { get; set; }
}

public class Group
{
    [Key] // *** add this attribute
    public int GroupId { get; set; } // *** Change D to d to match ApplicationUserGroup property (this is just to be consistent in your naming conventions!)
    [Required]
    [StringLength(100, MinimumLength = 2)]
    public string Name { get; set; }

    public virtual List<ApplicationUserGroup> UserGroups { get; set; } // *** this has changed also
}

然后使用流畅的api配置这些关系,在DbContext类中添加以下代码:

protected override void OnModelCreating(DbModelBuilder mb)
{
    mb.Entity<ApplicationUser>()
            .HasMany(au => au.UserGroups)
            .WithRequired(ug => ug.ApplicationUser)
            .HasForeignKey(ug => ug.ApplicationUserId)
            .WillCascadeOnDelete(false);

    mb.Entity<Group>()
            .HasMany(grp => grp.UserGroups)
            .WithRequired(ug => ug.Group)
            .HasForeignKey(ug => ug.GroupId)
            .WillCascadeOnDelete();
}

在这种情况下,要在组中添加用户,您需要在ApplicationUserGroup表中添加一条记录,告知哪个用户添加到哪个组中(使用ApplicationUserId列和GroupId列),并且为了检查用户是否属于哪些组,您需要选择ApplicationUserGroupApplicationUserId列与该用户的ID匹配的所有记录。

希望这有帮助。