我有以下实体:
Privilege ( Id, Name )
Role ( Id, Name, ICollection<Privilege> )
System ( Id, Name )
User ( Id, Name, Pass, ? )
现在我想建模“一个用户可能拥有零个或多个系统中的每一个零个或多个角色”,例如:
IDictionary<System, ICollection<Role>> SystemRoles { get; set; }
ASP.NET EntityFramework可以实现吗?如果有,怎么样?我需要设置什么属性?
现在已经考虑了很长一段时间,但我没有在网上找到任何有用的“实体框架代码第一个三元关系”
你能指点我一些很好的链接吗?或者也许给我一个提示如何建模/我可以把哪些属性放在字典上?
其他问题:如果IDictionary解决方案以某种方式工作,是否有任何更改以获得更改跟踪代理性能? IDictionary不是ICollection ......
答案 0 :(得分:1)
用户可能拥有零个或多个系统中的每个系统零个或多个角色
您需要一个描述三者之间关系的实体:
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()
)。
修改强>
为了获得一个用户的字典,你可以引入一个帮助属性(readonly而不是映射到数据库),如下所示:
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
以启用延迟加载。