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