如何将用户/权限关系定义为M:M?

时间:2015-01-14 14:52:40

标签: c# .net entity-framework erd

Resource通过Action联接表/单独实体与Permission M M 相关联。用户可以拥有许多命名权限。可以为多个用户分配相同的权限。

如何将User - Permission关系定义为 M M ?它在 EF 中会是什么样子?

修改

  • 我应该将ResourceId和ActionId合并为 EF 中的主键吗?
  • 如何将PermissionUser关联呢?
  • 如何进行插入/选择?

将它映射成是正确的:

modelBuilder.Entity<User>()
    .HasMany(u => u.Permissions)
    .WithMany(p => p.Users)
    .Map(c => {
        c.MapLeftKey("ResourceId");
        c.MapLeftKey("ActivityId");
        c.ToTable("UserPermissions");
     });

如果Permission的定义如下:

public class Permission {
    public String Name { get; set; }

    public Int32 ResourceId { get; set; }
    public virtual Resource Resource { get; set; }

    public Int32 ActivityId { get; set; }
    public virtual Activity Activity { get; set; }

    public virtual ICollection<User> Users { get; set; }
}

User喜欢这样:

public class User : Entity {
    public String Username { get; set; }
    public String UserImagePath { get; set; }
    public String Password { get; set; }
    public virtual ISet<Permission> Permissions { get; set; }

    public User(String username, String password) {
        this.Username = username;
        this.Password = password;
        this.Permissions = new HashSet<Permission>();
    }
}

3 个答案:

答案 0 :(得分:4)

要在UserPermission之间创建多对多关系,您需要创建ICollection<>类型的两个navegation属性:

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Password { get; set; }

    public virtual ICollection<Permission> Permissions { get; set; }
}

public class Permission
{
    public int Id { get; set; }
    public string Name { get; set; }

    public int ResourceId { get; set; }
    public virtual Resource Resource { get; set; }

    public int ActionId { get; set; }
    public virtual Action Action { get; set; }

    public virtual ICollection<User> Users { get; set; }
}

Code First约定将承认多对多关系 并使用表的相应键在数据库中构建连接表 加盟。键是连接表的主键和指向的外键 连接表。通过组合名称来创建新表的名称 它正在加入的类,然后使结果多元化。

如果您愿意自己这样做,可以使用Fluent Api来完成。一种简单的方法是覆盖Context的OnModelCreating方法。我在下面举例说明了你的情况:

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
 {
        modelBuilder.Entity<User>().HasKey(p => p.Id);
        modelBuilder.Entity<User>().Property(u => u.Name).IsRequired();
        modelBuilder.Entity<User>().Property(u => u.Password).IsRequired();

        modelBuilder.Entity<Permission>().HasKey(p => p.Id);
        modelBuilder.Entity<Permission>().Property(u => u.Name).IsRequired();

        //configuring the many-to-many relationship
        modelBuilder.Entity<User>()
            .HasMany(u => u.Permissions)
            .WithMany(p => p.Users)
            .Map(c => c.ToTable("UserPermissions"));
 }

如您所见,您可以使用Fluent Api来指定您的人际关系。此外,您可以指定哪个适当的主要密钥,如果需要某个属性,依此类推。所有这些都可以使用Data Annotations来完成。

答案 1 :(得分:0)

为了在User和Permission之间建立多对多关系,只需添加相应的集合。 在用户和权限集合中添加权限集合。

这样的东西
User
...
...
<ICollection> Permissions


Permissions
....
....
<ICollection> Users

这有望添加一个新表,如PermissionsUsers或UsersPermissions。

答案 2 :(得分:0)

这是我得到的:

<强>的DbContext

public class AppDbContext : DbContext {
    public DbSet<User> Users { get; set; }
    public DbSet<RoleResourceActivity> RoleResourceActivities { get; set; }
    public DbSet<Activity> Activities { get; set; }
    public DbSet<Resource> Resources { get; set; }
    public DbSet<Role> Roles { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        modelBuilder.Entity<Activity>().HasKey(i => i.Id);
        modelBuilder.Entity<Resource>().HasKey(i => i.Id);
        modelBuilder.Entity<User>().HasKey(i => i.Id);
        modelBuilder.Entity<RoleResourceActivity>().HasKey(i => new {
            i.ResourceId, 
            i.ActivityId, 
            i.RoleId
        });

        base.OnModelCreating(modelBuilder);
    }

    public AppDbContext() : base("AppDb") { 
        Database.SetInitializer<AppDbContext>(new AppDbContextInitializer());
    }
}

<强>模型

public class RoleResourceActivity {
    public Int32 ResourceId { get; set; }
    public virtual Resource Resource { get; set; }

    public Int32 ActivityId { get; set; }
    public virtual Activity Activity { get; set; }

    public Int32 RoleId { get; set; }
    public virtual Role Role { get; set; }
}

public class User {
    public Int32 Id { get; set; }
    public String Username { get; set; }
    public String UserImagePath { get; set; }
    public String Password { get; set; }

    public virtual ISet<Role> Roles { get; set; }

    public User(String username, String password) : this() {
        this.Username = username;
        this.Password = password;
    }

    protected User() { 
        this.Roles = new HashSet<Role>();
    }
}

public class Role {
    public Int32 Id { get; set; }
    public String Name { get; set; }
    public virtual ISet<User> Users { get; set; }
    public virtual ISet<RoleResourceActivity> RoleResourceActivities { get; set; }

    public Role(String name) : this() { 
        this.Name = name;
    }

    protected Role() {
        this.Users = new HashSet<User>();
        this.RoleResourceActivities = new HashSet<RoleResourceActivity>();
    }
}

public class Resource {
    public Int32 Id { get; set; }
    public String Name { get; set; }
    public virtual ISet<RoleResourceActivity> RoleResourceActivities { get; set; }

    public Resource(String name) : this() {
        this.Name = name;
    }

    protected Resource() {
        this.RoleResourceActivities = new HashSet<RoleResourceActivity>();
    }
}

public class Activity {
    public Int32 Id { get; set; }
    public String Name { get; set; }
    public virtual ISet<RoleResourceActivity> RoleResourceActivities { get; set; }

    public Activity(String name) : this() {
        this.Name = name;
    }

    protected Activity() {
        this.RoleResourceActivities = new HashSet<RoleResourceActivity>();
    }
}