用户对系统的角色 - 如何(对象 - )模型三元关系? [英] User has roles for systems - how to (object-)model ternary relation?

查看:142
本文介绍了用户对系统的角色 - 如何(对象 - )模型三元关系?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下实体:

 特权(ID,姓名)
角色(ID,姓名,ICollection的<特级>)
系统(ID,姓名)

的用户(ID,姓名,通行证,)

现在我想模式,用户可以为每个零个或多个系统的零个或多个角色,例如:

 的IDictionary<系统,ICollection的<的角色和GT;> SystemRoles {搞定;组; } 



这是可能的ASP.NET的EntityFramework?如果是的话,怎么样?什么属性我必须设置?



一直在寻找相当一段时间了,但是我没有找到实体框架代码第一个三元任何东西在网络上有用关于



你能指出我到这是详细介绍一些不错的链接? ?或者,也许给我一个提示如何建模它/它的属性,我可以把字典



其他问题:如果IDictionary的解决方案可不知何故,没有任何变化得到更改跟踪代理性能? IDictionary的是不是一个ICollection的...


解决方案

一个用户可以对每个零个或多个系统零个或多个角色。




您将需要一个描述三者之间的关系的实体:

 公共类UserSystemRole 
{
公众诠释用户ID {搞定;组; }
公众诠释SYSTEMID {搞定;组; }
公众诠释角色ID {搞定;组; }

公众用户用户{搞定;组; }
公共系统系统{搞定;组; }
公共角色角色{搞定;组; }
}



我将创建所有三个属性的复合主键,因为每个组合可能只出现一次,并且必须在唯一的。关键的每个部分是相应的导航性能外键用户系统 。角色



那么其他的实体将有集合指的是这个链接实体:

 公共类用户
{
公众诠释用户ID {搞定;组; }
// ...
公众的ICollection< UserSystemRole> UserSystemRoles {搞定;组; }
}

公共类系统
{
公众诠释SYSTEMID {搞定;组; }
// ...
公众的ICollection< UserSystemRole> UserSystemRoles {搞定;组; }
}

公共类角色
{
公众诠释角色ID {搞定;组; }
// ...
公众的ICollection< UserSystemRole> UserSystemRoles {搞定;组; }
}



然后用流利的API映射是这样的:

  modelBuilder.Entity< UserSystemRole>()
.HasKey(USR =>新建{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 = GT; s.UserSystemRoles)
.HasForeignKey(USR => usr.SystemId);

modelBuilder.Entity< UserSystemRole>()
.HasRequired(USR => usr.Role)
.WithMany(R = GT; r.UserSystemRoles)
.HasForeignKey(USR => usr.RoleId);

您可以删除集合属性之一,如果你不需要他们(使用 WithMany()不带参数的话)。



修改



为了得到一个字典,你可以引入一个辅助属性(只读,而不是映射到数据库)的用户,像这样:

 公共类用户
{
公众诠释用户ID {搞定;组; }
// ...
公众的ICollection< UserSystemRole> UserSystemRoles {搞定;组; }

公众的IDictionary<系统,IEnumerable的<的角色和GT;> SystemRoles
{
得到
{
返回UserSystemRoles
.GroupBy(USR => usr.System)
.ToDictionary(G =>克键,G => g.Select(USR => usr.Role));
}
}
}

请注意,您需要加载与预先加载的 UserSystemRoles 属性首先,你可以访问此之前字典。或者可以选择标记 UserSystemRoles 属性作为虚拟启用延迟加载。


I've got the following Entities:

Privilege ( Id, Name )
Role ( Id, Name, ICollection<Privilege> )
System ( Id, Name )

User ( Id, Name, Pass, ? )

Now I want to model "A user may have for each of zero or more systems zero or more roles", e.g.:

IDictionary<System, ICollection<Role>> SystemRoles { get; set; }

Is this possible with ASP.NET EntityFramework? If yes, how? What attributes do I have to set?

Been looking around for quite some time now, however I don't find anything useful on the net for "entity framework code first ternary relation"

Can you point me to some nice link where this is covered in detail? Or maybe give me a hint how to model it / which attributes I can put on the dictionary?

Additional question: If the IDictionary solution works somehow, is there any change to get change tracking proxy performance? IDictionary is not an ICollection...

解决方案

A user may have for each of zero or more systems zero or more roles

You will need an entity that describes the relationship between the three:

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

I would create a composite primary key from all three properties because each combination may only occur once and must the unique. Each part of the key is a foreign key for the respective navigation property User, System and Role.

Then the other entities would have collections refering to this "link entity":

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

And then the mapping with Fluent API would look like this:

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

You can remove one of the collection properties if you don't need them (use WithMany() without parameter then).

Edit

In order to get a dictionary for a user you could introduce a helper property (readonly and not mapped to the database) like so:

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

Note that you need to load the UserSystemRoles property with eager loading first before you can access this dictionary. Or alternatively mark the UserSystemRoles property as virtual to enable lazy loading.

这篇关于用户对系统的角色 - 如何(对象 - )模型三元关系?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆