如何定义User/Permission关系为M:M?
How to define User/Permission relationship as M:M?
Resource
与 Action
的关系为 M:M 通过 Permission
加入 table/separate实体。用户可以有许多命名权限。同一权限可能分配给多个用户。
如何定义User
-Permission
关系为M:M?在 EF 中会是什么样子?
编辑
- 我应该在 EF 中组合 ResourceId 和 ActionId 作为主键吗?
- 那我怎么把
Permission
和User
联系起来呢?
- 如何制作inserts/selects?
这样映射对不对:
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>();
}
}
为了在 User 和 Permission 之间建立多对多关系,只需添加各自的集合。
在User中添加Permissions集合,在Permission中添加Users集合。
类似
User
...
...
<ICollection> Permissions
Permissions
....
....
<ICollection> Users
这有望添加一个新的 table,例如 PermissionsUsers 或 UsersPermissions。
要在 User
和 Permission
之间创建多对多关系,您需要创建两个 ICollection<>
类型的导航属性:
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 约定将识别多对多关系
并使用 tables 的适当键在数据库中构建一个连接 table
加盟。这些键都是连接 table 的主键和指向的外键
加入的 tables。新 table 的名称是通过组合以下名称创建的
类 它正在连接然后复数化结果。
如果您喜欢自己做,可以使用 Fluent Api。一种简单的方法是覆盖上下文的 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 而不仅仅是指定您的关系。此外,如果需要某些 属性,您可以指定哪个属性将是主键,因此 on.All 您也可以使用 Data Annotations.[=18= 来完成这些事情]
这是我得到的:
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>();
}
}
Resource
与 Action
的关系为 M:M 通过 Permission
加入 table/separate实体。用户可以有许多命名权限。同一权限可能分配给多个用户。
如何定义User
-Permission
关系为M:M?在 EF 中会是什么样子?
编辑
- 我应该在 EF 中组合 ResourceId 和 ActionId 作为主键吗?
- 那我怎么把
Permission
和User
联系起来呢? - 如何制作inserts/selects?
这样映射对不对:
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>();
}
}
为了在 User 和 Permission 之间建立多对多关系,只需添加各自的集合。 在User中添加Permissions集合,在Permission中添加Users集合。
类似
User
...
...
<ICollection> Permissions
Permissions
....
....
<ICollection> Users
这有望添加一个新的 table,例如 PermissionsUsers 或 UsersPermissions。
要在 User
和 Permission
之间创建多对多关系,您需要创建两个 ICollection<>
类型的导航属性:
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 约定将识别多对多关系 并使用 tables 的适当键在数据库中构建一个连接 table 加盟。这些键都是连接 table 的主键和指向的外键 加入的 tables。新 table 的名称是通过组合以下名称创建的 类 它正在连接然后复数化结果。
如果您喜欢自己做,可以使用 Fluent Api。一种简单的方法是覆盖上下文的 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 而不仅仅是指定您的关系。此外,如果需要某些 属性,您可以指定哪个属性将是主键,因此 on.All 您也可以使用 Data Annotations.[=18= 来完成这些事情]
这是我得到的:
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>();
}
}