使用身份 2 和 Entity Framework 6 在 IdentityUserRoles table 上额外 column/field
Extra column/field on IdentityUserRoles table using Identity 2 and Entity Framework 6
我在我的项目中使用了 IdentityUser class 的自定义实现。
问题是 Entity Framework 在 table IdentityUserRoles 中添加了一个额外的列,将子 class Id 映射为约束。
我知道 EF 可能对如何映射与这个新 class 的关系感到困惑,我只是不知道为什么以及如何解决它。我一直在网上搜索有关此 EF 行为的信息,但尚未找到解决方案。
以下是总结问题的一些屏幕截图:
无法提供完整的技术解释,但我在代码中进行了这些更改以解决问题:
public class ResultzContext : IdentityDbContext<ApplicationUser>
{
public ResultzContext()
: base("ResultzConnection")
{
}
static ResultzContext()
{
// Set the database intializer which is run once during application start
// This seeds the database with admin user credentials and admin role
Database.SetInitializer<ResultzContext>(new ApplicationDbInitializer());
}
public static ResultzContext Create()
{
return new ResultzContext();
}
:
:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
//modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id).ToTable("AspNetRoles");
//modelBuilder.Entity<IdentityUser>().ToTable("AspNetUsers");
modelBuilder.Entity<ApplicationUser>().ToTable("AspNetUsers");
//modelBuilder.Entity<IdentityUserLogin>().HasKey(l => new { l.UserId, l.LoginProvider, l.ProviderKey }).ToTable("AspNetUserLogins");
//modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId }).ToTable("AspNetUserRoles");
//modelBuilder.Entity<IdentityUserClaim>().ToTable("AspNetUserClaims");
因此,通常注释掉所有内容并将 IdentityUser 更改为 ApplicationUser。但需要补充一点,我最初有 Identity 1.0 的代码
希望对您有所帮助!
所以,我重新检查了我的数据库映射,我想我已经找到了解决这个问题的方法:
我的用户 class 映射位于另一个继承自 EntityTypeConfiguration 的文件 (UsuarioMap) 中,然后我将在其构造函数中指定我的配置,就像 post 中的图像一样。 (恕我直言,这更适合代码组织)。现在我的 IdentityUser (Usuario) table 配置只是位于 OnModelCreating 方法中:
modelBuilder.Entity<Usuario>().ToTable("Usuario");
modelBuilder.Entity<Usuario>().Property(u => u.UserName).IsRequired();
modelBuilder.Entity<Usuario>().Property(u => u.Email).IsRequired();
modelBuilder.Entity<Usuario>().Property(u => u.PasswordHash).IsRequired();
modelBuilder.Entity<Usuario>().Property(u => u.Nome).IsRequired();
modelBuilder.Entity<Usuario>().Property(u => u.DataRegistro).IsRequired();
modelBuilder.Entity<Usuario>().Property(u => u.UltimoLogin).IsOptional();
modelBuilder.Entity<Usuario>().HasOptional(u => u.Cliente).WithMany(c => c.Usuarios);
老实说,我不知道为什么 Entity Framework 以不同的方式看待这两个配置路径,因为 modelBuilder.Configurations.Add() 的参数和 return 的 modelBuilder.Entity() 是一个 System.Data.Entity.ModelConfiguration.EntityTypeConfiguration 对象,所以逻辑上两种方式都应该有效。
我发现了同样的问题。有一个更简单的解决方案。您应该在 IdentityUserRole 配置中明确定义关系。
例如:
public class UserRoleConfiguration : EntityTypeConfiguration<UserRole>
{
public UserRoleConfiguration()
{
HasKey(x => new {x.UserId, x.RoleId});
HasRequired(x => x.User).WithMany(x => x.Roles).WillCascadeOnDelete();
}
}
我在我的项目中使用了 IdentityUser class 的自定义实现。
问题是 Entity Framework 在 table IdentityUserRoles 中添加了一个额外的列,将子 class Id 映射为约束。
我知道 EF 可能对如何映射与这个新 class 的关系感到困惑,我只是不知道为什么以及如何解决它。我一直在网上搜索有关此 EF 行为的信息,但尚未找到解决方案。
以下是总结问题的一些屏幕截图:
无法提供完整的技术解释,但我在代码中进行了这些更改以解决问题:
public class ResultzContext : IdentityDbContext<ApplicationUser>
{
public ResultzContext()
: base("ResultzConnection")
{
}
static ResultzContext()
{
// Set the database intializer which is run once during application start
// This seeds the database with admin user credentials and admin role
Database.SetInitializer<ResultzContext>(new ApplicationDbInitializer());
}
public static ResultzContext Create()
{
return new ResultzContext();
}
: :
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
//modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id).ToTable("AspNetRoles");
//modelBuilder.Entity<IdentityUser>().ToTable("AspNetUsers");
modelBuilder.Entity<ApplicationUser>().ToTable("AspNetUsers");
//modelBuilder.Entity<IdentityUserLogin>().HasKey(l => new { l.UserId, l.LoginProvider, l.ProviderKey }).ToTable("AspNetUserLogins");
//modelBuilder.Entity<IdentityUserRole>().HasKey(r => new { r.RoleId, r.UserId }).ToTable("AspNetUserRoles");
//modelBuilder.Entity<IdentityUserClaim>().ToTable("AspNetUserClaims");
因此,通常注释掉所有内容并将 IdentityUser 更改为 ApplicationUser。但需要补充一点,我最初有 Identity 1.0 的代码 希望对您有所帮助!
所以,我重新检查了我的数据库映射,我想我已经找到了解决这个问题的方法:
我的用户 class 映射位于另一个继承自 EntityTypeConfiguration 的文件 (UsuarioMap) 中,然后我将在其构造函数中指定我的配置,就像 post 中的图像一样。 (恕我直言,这更适合代码组织)。现在我的 IdentityUser (Usuario) table 配置只是位于 OnModelCreating 方法中:
modelBuilder.Entity<Usuario>().ToTable("Usuario");
modelBuilder.Entity<Usuario>().Property(u => u.UserName).IsRequired();
modelBuilder.Entity<Usuario>().Property(u => u.Email).IsRequired();
modelBuilder.Entity<Usuario>().Property(u => u.PasswordHash).IsRequired();
modelBuilder.Entity<Usuario>().Property(u => u.Nome).IsRequired();
modelBuilder.Entity<Usuario>().Property(u => u.DataRegistro).IsRequired();
modelBuilder.Entity<Usuario>().Property(u => u.UltimoLogin).IsOptional();
modelBuilder.Entity<Usuario>().HasOptional(u => u.Cliente).WithMany(c => c.Usuarios);
老实说,我不知道为什么 Entity Framework 以不同的方式看待这两个配置路径,因为 modelBuilder.Configurations.Add() 的参数和 return 的 modelBuilder.Entity() 是一个 System.Data.Entity.ModelConfiguration.EntityTypeConfiguration 对象,所以逻辑上两种方式都应该有效。
我发现了同样的问题。有一个更简单的解决方案。您应该在 IdentityUserRole 配置中明确定义关系。
例如:
public class UserRoleConfiguration : EntityTypeConfiguration<UserRole>
{
public UserRoleConfiguration()
{
HasKey(x => new {x.UserId, x.RoleId});
HasRequired(x => x.User).WithMany(x => x.Roles).WillCascadeOnDelete();
}
}