实体框架6代码优先 - 用户UserRole权限多对多

时间:2014-06-02 18:32:10

标签: entity-framework orm mapping many-to-many fluent-interface

我正在使用EF6 Code First和流畅的API。我在用户,角色和权限之间有很多关系。用户有很多角色,反之亦然(但我对从角色导航到用户不感兴趣)。角色有很多权限,反之亦然(但我对从Permissions到Roles的导航不感兴趣)。

我的数据库结构(本例简化):

User = (UserId, Name)
UserRole = (UserRoleId, Name)
UserUserRole = (UserId, UserRoleId)
UserPermission = (UserPermissionId, Name)
UserRoleUserPermission = (UserRoleId, UserPermissionId)

我的C#课程是:

public class User
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Password { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public DateTime DateCreated { get; set; }
        public DateTime DateUpdated { get; set; }
        public virtual IList<Role> Roles { get; set; }
        public bool Active { get; set; }
    }

public class Role
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public bool Active { get; set; }
        public virtual IList<Permission> Permissions { get; set; }
    }

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

我的映射是:

// User
            modelBuilder.Entity<User>().ToTable("User");
            modelBuilder.Entity<User>().Property(p => p.Id).HasColumnName("UserId");
            modelBuilder.Entity<User>().Property(p => p.DateCreated).HasColumnName("DateCreated");
            modelBuilder.Entity<User>().Property(p => p.DateUpdated).HasColumnName("DateUpdated");
            modelBuilder.Entity<User>().Property(p => p.Email).HasColumnName("Email");
            modelBuilder.Entity<User>().Property(p => p.FirstName).HasColumnName("FirstName");
            modelBuilder.Entity<User>().Property(p => p.LastName).HasColumnName("LastName");
            modelBuilder.Entity<User>().Property(p => p.Name).HasColumnName("Name");
            modelBuilder.Entity<User>().Property(p => p.Password).HasColumnName("Password");
            modelBuilder.Entity<User>().HasMany(p => p.Roles).WithMany().Map(p => 
            { 
                p.ToTable("UserUserRole");
                p.MapLeftKey("UserId");
                p.MapRightKey("UserRoleId");
            });
            modelBuilder.Entity<User>().Property(p => p.Active).HasColumnName("IsActive");

            // UserRole
            modelBuilder.Entity<Role>().ToTable("UserRole");
            modelBuilder.Entity<Role>().Property(p => p.Id).HasColumnName("UserRoleId");
            modelBuilder.Entity<Role>().Property(p => p.Name).HasColumnName("Name");
            modelBuilder.Entity<Role>().HasMany(p => p.Permissions).WithMany().Map(p =>
            {
                p.ToTable("UserRoleUserPermission");
                p.MapLeftKey("UserRoleId");
                p.MapRightKey("UserPermissionId");
            });
            modelBuilder.Entity<Role>().Property(p => p.Active).HasColumnName("IsActive");

            // UserPermission
            modelBuilder.Entity<Permission>().ToTable("UserPermission");
            modelBuilder.Entity<Permission>().Property(p => p.Id).HasColumnName("UserPermissionId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
            modelBuilder.Entity<Permission>().Property(p => p.Name).HasColumnName("Name");
            modelBuilder.Entity<Permission>().Property(p => p.Active).HasColumnName("IsActive");

这是我得到的错误:

在模型生成期间检测到一个或多个验证错误:

UserRoleId:名称:类型中的每个属性名称必须是唯一的。已定义属性名称“UserRoleId”。 UserRole_RolePermission ::关系约束中的从属角色和主要角色中的属性数必须相同。

1 个答案:

答案 0 :(得分:1)

我真的不喜欢我如何解决这个问题,我确信必须有更好的方法。显然,列名存在问题(可能是EF中的错误),因为我的主键名称与复合主键的名称相同,我映射了所有属性,指示映射db列。因此,我重命名了我的类,以避免必须在主键上指定列映射并解决了问题。

C#类:

public class User
    {
        public int UserId { get; set; }
        public string Name { get; set; }
        public string Password { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public DateTime DateCreated { get; set; }
        public DateTime DateUpdated { get; set; }
        public virtual ICollection<UserRole> Roles { get; set; }
        public bool Active { get; set; }
    }

public class UserRole
    {
        public int UserRoleId { get; set; }
        public string Name { get; set; }
        public bool Active { get; set; }
        public virtual ICollection<UserPermission> Permissions { get; set; }
    }

public class UserPermission
    {
        public int UserPermissionId { get; set; }
        public string Name { get; set; }
        public bool Active { get; set; }
    }

EF Mapping:

// User
            modelBuilder.Entity<User>().ToTable("User");
            modelBuilder.Entity<User>().Property(p => p.UserId).HasColumnName("UserId");
            modelBuilder.Entity<User>().Property(p => p.Name).HasColumnName("Name");
            modelBuilder.Entity<User>().Property(p => p.Password).HasColumnName("Password");
            modelBuilder.Entity<User>().Property(p => p.Email).HasColumnName("Email");
            modelBuilder.Entity<User>().Property(p => p.FirstName).HasColumnName("FirstName");
            modelBuilder.Entity<User>().Property(p => p.LastName).HasColumnName("LastName");
            modelBuilder.Entity<User>().Property(p => p.DateCreated).HasColumnName("DateCreated");
            modelBuilder.Entity<User>().Property(p => p.DateUpdated).HasColumnName("DateUpdated");
            modelBuilder.Entity<User>().HasMany(p => p.Roles).WithMany().Map(p => 
            { 
                p.ToTable("UserUserRole");
                p.MapLeftKey("UserId");
                p.MapRightKey("UserRoleId");
            });
            modelBuilder.Entity<User>().Property(p => p.Active).HasColumnName("IsActive");

            // UserRole
            modelBuilder.Entity<UserRole>().ToTable("UserRole");
            modelBuilder.Entity<UserRole>().Property(p => p.Name).HasColumnName("Name");
            modelBuilder.Entity<UserRole>().HasMany(p => p.Permissions).WithMany().Map(p =>
            {
                p.ToTable("UserRoleUserPermission");
                p.MapLeftKey("UserRoleId");
                p.MapRightKey("UserPermissionId");
            });
            modelBuilder.Entity<UserRole>().Property(p => p.Active).HasColumnName("IsActive");

            // UserPermission
            modelBuilder.Entity<UserPermission>().ToTable("UserPermission");
            modelBuilder.Entity<UserPermission>().Property(p => p.UserPermissionId).HasColumnName("UserPermissionId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
            modelBuilder.Entity<UserPermission>().Property(p => p.Name).HasColumnName("Name");
            modelBuilder.Entity<UserPermission>().Property(p => p.Active).HasColumnName("IsActive");

我希望找到更好的方法,因为我对这个解决方案不满意,但至少它可行,我可以继续开发应用程序。

编辑:

我对我的类做了一些更改,这个映射也有效:

因此,只有在将UserRole类重命名为Role时才会出现问题。它必须是与数据库表UserUserRole相关的东西,也许映射到此表的属性(ToTable属性)不能按预期工作。

// User
            modelBuilder.Entity<User>().ToTable("User");
            modelBuilder.Entity<User>().Property(p => p.Id).HasColumnName("UserId");
            modelBuilder.Entity<User>().Property(p => p.Name).HasColumnName("Name");
            modelBuilder.Entity<User>().Property(p => p.Password).HasColumnName("Password");
            modelBuilder.Entity<User>().Property(p => p.Email).HasColumnName("Email");
            modelBuilder.Entity<User>().Property(p => p.FirstName).HasColumnName("FirstName");
            modelBuilder.Entity<User>().Property(p => p.LastName).HasColumnName("LastName");
            modelBuilder.Entity<User>().Property(p => p.DateCreated).HasColumnName("DateCreated");
            modelBuilder.Entity<User>().Property(p => p.DateUpdated).HasColumnName("DateUpdated");
            modelBuilder.Entity<User>().HasMany(p => p.Roles).WithMany().Map(p => 
            { 
                p.ToTable("UserUserRole");
                p.MapLeftKey("UserId");
                p.MapRightKey("UserRoleId");
            });
            modelBuilder.Entity<User>().Property(p => p.Active).HasColumnName("IsActive");

            // UserRole
            modelBuilder.Entity<UserRole>().ToTable("UserRole");
            modelBuilder.Entity<UserRole>().HasKey(p => p.Id).Property(p => p.Id).HasColumnName("UserRoleId");
            modelBuilder.Entity<UserRole>().Property(p => p.Name).HasColumnName("Name");
            modelBuilder.Entity<UserRole>().HasMany(p => p.Permissions).WithMany().Map(p =>
            {
                p.ToTable("UserRoleUserPermission");
                p.MapLeftKey("UserRoleId");
                p.MapRightKey("UserPermissionId");
            });
            modelBuilder.Entity<UserRole>().Property(p => p.Active).HasColumnName("IsActive");
相关问题