1

使用实体框架4和代码首先我将如何创建支持此方案的模型:EF 4代码优先和M2M2M

在应用程序中,有个用户,每个用户都属于一个组和每个组用户可以有一个更多角色。

例子:

我想能够说,“给我丽莎”,响应返回用户对象丽莎,与她所属的组。对于每个组都有一个列表属性,她具有该特定组的所有角色

任何人都可以帮助我使用代码先对任何帮助/代码示例进行建模,这将非常棒!

/最好的问候Vinblad

回答

2

编辑:这是您要求新模式。

public class User 
{ 
    public virtual int Id { get; set; } 
    public virtual ICollection<UserPermission> Permissions { get; set; } 
} 

// Permission is extended junction table to model M:N between 
// User and Group but in addition it contains relation to Roles. 
// The ony disadvantage is that this model doesn't control that 
// role in the collection is also the role related to group. You 
// must either enforce it in application logic or create some additional 
// database construct to check it. 
public class UserPermission 
{ 
    public virtual int UserId { get; set; } 
    public virtual int GroupId { get; set; } 

    public virtual Group Group { get; set; } 
    public virtual ICollection<Role> Roles { get; set; } 
} 

public class Group 
{ 
    public virtual int Id { get; set; } 
    public virtual ICollection<UserPermission> UserPermissions { get; set; } 
    public virtual ICollection<Role> Roles { get; set; } 
} 


public class Role 
{ 
    public virtual int Id { get; set; } 
    public virtual ICollection<Group> Groups { get; set; } 
    public virtual ICollection<UserPermission> UserPermissions { get; set; } 
} 

public class Context : DbContext 
{ 
    public DbSet<User> Users { get; set; } 
    public DbSet<Group> Groups { get; set; } 
    public DbSet<Role> Roles { get; set; } 
    public DbSet<UserPermission> UserPermissions { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     base.OnModelCreating(modelBuilder); 

     // Permission has composite key 
     modelBuilder.Entity<UserPermission>() 
      .HasKey(p => new {p.UserId, p.GroupId}); 

     // Permission doesn't have navigation property to user 
     modelBuilder.Entity<User>() 
      .HasMany(u => u.Permissions) 
      .WithRequired() 
      .HasForeignKey(p => p.UserId); 

     modelBuilder.Entity<Group>() 
      .HasMany(g => g.UserPermissions) 
      .WithRequired(p => p.Group) 
      .HasForeignKey(p => p.GroupId); 
    } 
} 

如代码中所述,存在小的缺点。您可以通过使用额外的FK强制数据库中的数据完整性来避免这种缺陷,而这种额外的FK不能由代码先建模。您可以使用自定义的初始化补充说FK:

public class CustomInitializer : DropCreateDatabaseIfModelChanges<Context> 
{ 
    protected override void Seed(Context context) 
    { 
     context.Database.ExecuteSqlCommand(
      @"ALTER TABLE [dbo].[RoleUserPermissions] 
      WITH CHECK ADD CONSTRAINT [FK_RoleUserPermissions_RoleGroups] 
      FOREIGN KEY([Role_Id], [UserPermission_GroupId]) 
      REFERENCES [dbo].[RoleGroups] ([Role_Id], [Group_Id])"); 
    } 
} 

只需添加到您的应用程序初始化(仅用于调试 - 应用程序不应该能够删除其发布的数据库):

Database.SetInitializer(new CustomInitializer()); 
+0

谢谢拉迪斯拉夫,但我不知道这是否正确。如果我提取用户,我可以选择他/她所属的组,但是如果我阅读了此权限,我将无法查看用户对某个组的角色。这将返回为该组添加的所有角色,而不是属于该组的用户。我希望能够说,“给我Lisa”,并且响应返回lisa的用户对象,以及她所属的组。对于每个组,都有一个列表属性,包含她为该特定组的所有角色。 – Vinblad 2011-03-21 09:11:31

+0

所以它是完全不同的要求。我会考虑的。 – 2011-03-21 09:36:50

+0

对不起,我在第一次描述时清楚地写道:“每个用户属于一个或多个组,每个用户可以拥有一个或多个角色”。希望你现在可以帮我理解我的要求。 – Vinblad 2011-03-21 09:53:43