Sql 异常:.net 核心项目使用的现有 .net 框架标识数据库中的列名称无效 "NormalizedUserName..."

Sql Exeption: Invalid column name "NormalizedUserName..." in existing .net framework identiy db used by .net core project

我在 .Net Framework 中有一个项目。我使用 .Net Framework 和 .Net Framework Asp.net 标识。这里没有问题...

现在我正在创建一个新项目。这是一个必须连接到现有数据库的 .Net Core 2.2 项目。我无法更改数据库的结构。我已经用这个命令搭建了数据库

Scaffold-DbContext -Connection "..." -Provider Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyDatabaseContext -Tables "Profile", <other_tables_no_identity> 

这样数据库就搭建好了,那我手动修改了以下文件

  1. 我已将 IdentityUser 添加到 Profile 实体
   public partial class Profile : IdentityUser {...}
  1. 我把OnModelCreating修改成这样:
 protected override void OnModelCreating(ModelBuilder modelBuilder)
 {
     //I have added this lines
     base.OnModelCreating(modelBuilder); 

     modelBuilder.Entity<IdentityUser>(entity =>
     {
         entity.ToTable("BaseProfile");

         entity.Property(e => e.Id)
                 .HasMaxLength(128)
                 .ValueGeneratedNever();

         entity.Property(e => e.Email)
                 .IsRequired()
                 .HasMaxLength(256);

         entity.Property(e => e.UserName)
                 .IsRequired()
                 .HasMaxLength(256);
         });

     modelBuilder.Entity<Profile>(entity =>
     {
         entity.ToTable("Profile");

         entity.HasIndex(e => e.Id)
                 .HasName("IX_Id");

         entity.Property(e => e.Id)
                 .HasMaxLength(128)
                 .ValueGeneratedNever();

         entity.Property(e => e.CreationDate).HasColumnType("datetime");

         entity.Property(e => e.LastAccessDate).HasColumnType("datetime");

         entity.Property(e => e.Rating).HasColumnType("decimal(18, 2)");
     });

     modelBuilder.Entity<IdentityUserRole<string>>().ToTable("ProfileRoleAssociation");
     modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("ProfileLoginAssociation");
     modelBuilder.Entity<IdentityUserClaim<int>>().ToTable("ProfileClaimAssociation");
     modelBuilder.Entity<IdentityRole>().ToTable("ProfileRole");


 }

我已经从旧的 .Net Framework 项目中复制了这些行...但是当我尝试登录时出现此错误:

An unhandled exception occurred while processing the request. SqlException: Invalid column name 'NormalizedUserName'. Invalid column name 'AccessFailedCount'. Invalid column name 'ConcurrencyStamp'. Invalid column name 'Email'. Invalid column name 'EmailConfirmed'. Invalid column name 'LockoutEnabled'. Invalid column name 'LockoutEnd'. Invalid column name 'NormalizedEmail'. Invalid column name 'NormalizedUserName'. Invalid column name 'PasswordHash'. Invalid column name 'PhoneNumber'. Invalid column name 'PhoneNumberConfirmed'. Invalid column name 'SecurityStamp'. Invalid column name 'TwoFactorEnabled'. Invalid column name 'UserName'.

列名NormalizedUserName不存在。但其他的是。

怎么了?谢谢

编辑

我知道问题是关于继承的。它在 Profile table 中查找列而不是 BaseProfile... 但我仍然不明白如何解决它。

有点复杂,因为我无法修改原始的 .net 框架应用程序....

这里是老.net framework项目中的情况: 我有一个 profile class 继承自 IdentityUser.

public class Profile : IdentityUser { ... }

那么OnModelCreating我有这个

var baseProfile = modelBuilder.Entity<IdentityUser>().ToTable("BaseProfile");
modelBuilder.Entity<Profile>().ToTable("Profile");
modelBuilder.Entity<IdentityUserRole>().ToTable("ProfileRoleAssociation");
modelBuilder.Entity<IdentityUserLogin>().ToTable("ProfileLoginAssociation");
modelBuilder.Entity<IdentityUserClaim>().ToTable("ProfileClaimAssociation");
modelBuilder.Entity<IdentityRole>().ToTable("ProfileRole");

所以,那是我无法改变的初始情况。

好吧,在我的新 .net 核心项目中,我在 PackageManager Console:

中启动了这个命令
    Scaffold-DbContext -Connection {connection_string} -Provider Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Context MyContext -Tables "Profile", "BaseProfile", <other_tables>

注意 BaseProfile 不是 .net 框架中的实体。请注意,出于某种原因,该命令不会生成 IdentityUser class 中定义的属性。所以,我修改了自动生成的 class 如下:

public partial class BaseProfile : IdentityUser
{
    public override string Id { get; set; }
    public override string Email { get; set; }
    public override bool EmailConfirmed { get; set; }
    public override string PasswordHash { get; set; }
    public override string SecurityStamp { get; set; }
    public override string PhoneNumber { get; set; }
    public override bool PhoneNumberConfirmed { get; set; }
    public override bool TwoFactorEnabled { get; set; }
    public DateTime? LockoutEndDateUtc { get; set; }
    public override bool LockoutEnabled { get; set; }
    public override int AccessFailedCount { get; set; }
    public override string UserName { get; set; }

    public override string NormalizedEmail { get { return this.Email.ToUpperInvariant(); } }
    public override string NormalizedUserName { get { return this.UserName.ToUpperInvariant(); } }
    public virtual Profile Profile { get; set; }
}

我修改了 BaseProfile,使其继承自 IdentityUser。所有由脚手架命令自动生成并在 IdentityUser class 中定义的属性都已被覆盖。不要删除它们,即使它们在 IdentityUser 中定义也不会绑定到数据库。 我还创建了两个新属性:

public override string NormalizedEmail { get { return this.Email.ToUpperInvariant(); } }
public override string NormalizedUserName { get { return this.UserName.ToUpperInvariant(); } }

Normalized* 旧版本的 MS Identity 中不存在属性。但它们对于新的来说是必要的。这两个属性需要让用户登录。事实上,用户在登录期间的输入是与这两个属性进行比较的。好吧,这不是该属性的最正确实现。但是我的文化还可以。

最后,OnModelCreating 我添加了这些行:

modelBuilder.Entity<BaseProfile>(entity =>
{
    entity.ToTable("BaseProfile");
    entity.Ignore(e => e.LockoutEnd);
    entity.Ignore(e => e.ConcurrencyStamp);
    entity.Ignore(e => e.NormalizedEmail);
    entity.Ignore(e => e.NormalizedUserName);
    entity.Ignore(e => e.LockoutEnd);
});

这些属性不在旧版本的 Identity 中,而只在新版本中。