我正在使用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 ::关系约束中的从属角色和主要角色中的属性数必须相同。
答案 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");