自定义class身份/Entity Framework多对多关系

Custom class Identity / Entity Framework many-to-many relationship

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

尝试实施 "group" 功能时遇到问题... 我实施了休闲(基于此: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; }
}

和 link class 有一个额外的属性(状态):

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

我设法将我的 table 作为 ApplicationUserGroups 放入我的数据库,但实体不断生成另一个 table 没有我的状态字段的 GroupApplicationUsers...

我认为问题出在身份上,有人可以帮助我吗?

PS: 对不起我的英语不好,我是法语^^

您需要使用适当的属性装饰您的实体属性或使用流利的 api 让 EF 理解您正在尝试做什么。因此,在您的 DbContext class 中使用流利的 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 entity/table 作为多对多关系的连接点 table。

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

首先更改您的实体 classes 如下:

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
}

然后使用 fluent api 配置这些关系,在 DbContext class 中添加以下代码:

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 table 中添加一条记录,以告知将哪个用户添加到哪个组中(使用 ApplicationUserId 列和 GroupId 列),另外要检查用户属于哪些组,您需要 select ApplicationUserGroup 中的所有记录,其中他们的 ApplicationUserId 列与该用户的 ID 相匹配用户。

希望对您有所帮助。