对于零个或多个系统中的每一个,用户可能具有零个或多个角色
您将需要一个描述三者之间关系的实体:
public class UserSystemRole
{
public int UserId { get; set; }
public int SystemId { get; set; }
public int RoleId { get; set; }
public User User { get; set; }
public System System { get; set; }
public Role Role { get; set; }
}
我会从所有三个属性创建一个复合主键,因为每个组合可能只出现一次并且必须是唯一的。键的每个部分都是相应导航属性的外键User
,System
并且Role
.
然后其他实体将拥有引用此“链接实体”的集合:
public class User
{
public int UserId { get; set; }
//...
public ICollection<UserSystemRole> UserSystemRoles { get; set; }
}
public class System
{
public int SystemId { get; set; }
//...
public ICollection<UserSystemRole> UserSystemRoles { get; set; }
}
public class Role
{
public int RoleId { get; set; }
//...
public ICollection<UserSystemRole> UserSystemRoles { get; set; }
}
然后使用 Fluent API 的映射将如下所示:
modelBuilder.Entity<UserSystemRole>()
.HasKey(usr => new { usr.UserId, usr.SystemId, usr.RoleId });
modelBuilder.Entity<UserSystemRole>()
.HasRequired(usr => usr.User)
.WithMany(u => u.UserSystemRoles)
.HasForeignKey(usr => usr.UserId);
modelBuilder.Entity<UserSystemRole>()
.HasRequired(usr => usr.System)
.WithMany(s => s.UserSystemRoles)
.HasForeignKey(usr => usr.SystemId);
modelBuilder.Entity<UserSystemRole>()
.HasRequired(usr => usr.Role)
.WithMany(r => r.UserSystemRoles)
.HasForeignKey(usr => usr.RoleId);
如果不需要它们,您可以删除其中一个集合属性(WithMany()
然后使用不带参数)。
编辑
为了获取用户的字典,您可以引入一个辅助属性(只读且未映射到数据库),如下所示:
public class User
{
public int UserId { get; set; }
//...
public ICollection<UserSystemRole> UserSystemRoles { get; set; }
public IDictionary<System, IEnumerable<Role>> SystemRoles
{
get
{
return UserSystemRoles
.GroupBy(usr => usr.System)
.ToDictionary(g => g.Key, g => g.Select(usr => usr.Role));
}
}
}
请注意,您需要先UserSystemRoles
通过预先加载加载属性,然后才能访问此字典。或者将UserSystemRoles
属性标记为virtual
启用延迟加载。