自定义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 相匹配用户。
希望对您有所帮助。
我在 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 相匹配用户。
希望对您有所帮助。