C# 用户具有系统角色-如何(对象)建模三元关系?
我有以下实体:C# 用户具有系统角色-如何(对象)建模三元关系?,c#,entity-framework,entity-framework-5,C#,Entity Framework,Entity Framework 5,我有以下实体: Privilege ( Id, Name ) Role ( Id, Name, ICollection<Privilege> ) System ( Id, Name ) User ( Id, Name, Pass, ? ) 权限(Id、名称) 角色(Id、名称、ICollection) 系统(Id、名称) 用户(Id、名称、通行证、) 现在,我想对“一个用户可能拥有零个或多个系统中的每一个系统零个或多个角色”进行建模,例如: IDictionary系统角色{ge
Privilege ( Id, Name )
Role ( Id, Name, ICollection<Privilege> )
System ( Id, Name )
User ( Id, Name, Pass, ? )
权限(Id、名称)
角色(Id、名称、ICollection)
系统(Id、名称)
用户(Id、名称、通行证、)
现在,我想对“一个用户可能拥有零个或多个系统中的每一个系统零个或多个角色”进行建模,例如:
IDictionary系统角色{get;set;}
ASP.NET EntityFramework是否可以实现这一点?如果是,如何进行?我必须设置哪些属性
我已经四处寻找了很长一段时间,但是我在网上没有发现任何关于“实体框架代码优先三元关系”的有用信息
你能给我指一些很好的链接吗?这里有详细的介绍?或者给我一个如何建模的提示/哪些属性可以放在字典上
附加问题:如果IDictionary解决方案以某种方式工作,是否有任何更改以获得更改跟踪代理性能?IDictionary不是一个ICollection
对于零个或多个系统中的每一个,用户可能具有零个或多个角色
您需要一个实体来描述这三者之间的关系:
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; }
}
我将从所有三个属性创建一个复合主键,因为每个组合只能出现一次,并且必须是唯一的。键的每个部分都是相应导航属性用户
、系统
和角色
的外键
然后其他实体将拥有引用此“链接实体”的集合:
请注意,在访问此词典之前,您需要先使用“急切加载”加载
UserSystemRoles
属性。或者,将UserSystemRoles
属性标记为virtual
,以启用延迟加载。a)因此,如果没有中间类,则无法执行此操作?b) 我是EF新手,是否需要在中间类中包含UserId和User?仅仅让用户在那里还不够吗?@D.R.:(a)不。从数据库模式的角度来看就行了。您需要这样一个具有三个Id列的表来描述关系,因此您需要这样一个实体。(b) 好的,您可以不使用外键属性UserId
,但是您必须发明一个替代的主键属性,就像自动递增的Id
。在我看来,“三键”更好,因为它会自动唯一。从业务角度来看,允许这三列的组合重复是没有意义的。@D.R:关于字典,我在回答中添加了一个编辑部分。@D.R:不,主键属性必须存在于类中,并且必须是基元属性(int
,string
,等等),它们不能是导航属性。@D.R:是的,对于这些属性名称,它是按约定工作的。实际上只需要HasKey
。
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; }
}
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; }
}
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);
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));
}
}
}