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>
这样数据库就搭建好了,那我手动修改了以下文件
- 我已将
IdentityUser
添加到 Profile
实体
public partial class Profile : IdentityUser {...}
- 我把
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 中,而只在新版本中。
我在 .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>
这样数据库就搭建好了,那我手动修改了以下文件
- 我已将
IdentityUser
添加到Profile
实体
public partial class Profile : IdentityUser {...}
- 我把
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 中,而只在新版本中。