0

我有以下实体:

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 ...

4

1 回答 1

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

我会从所有三个属性创建一个复合主键,因为每个组合可能只出现一次并且必须是唯一的。键的每个部分都是相应导航属性的外键UserSystem并且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启用延迟加载。

于 2013-04-20T12:13:10.010 回答