具有一对多关系的自定义身份用户类在数据库中创建额外的列

问题描述

我在 ASP.NET Core Identity 上使用 Entity Framework Core.NET 5,对 postgresql 数据库使用代码优先方法

我正在尝试像这样扩展身份类

public class User : IdentityUser<int>
{
    public ICollection<UserLogin> Logins { get; set; }
}

public class UserLogin : IdentityUserLogin<int>
{
    public User User { get; set; }
}

public sealed class AppDbContext : IdentityDbContext<User,Role,int,UserClaim,UserRole,UserLogin,RoleClaim,UserToken>
{
    public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
    {
    }
}

但是,当我运行迁移时,它生成的表看起来像这样 -

enter image description here

请注意,已经创建了一个额外的列 UserId1

我希望它能够识别 UserLogin.User 导航的 Id 应该对应于 IdentityUserLogin.UserId 属性(根据 MS 在此处制定的约定:https://docs.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key) .

我也尝试过覆盖 IdentityUserLogin.UserId 但没有成功:

public class UserLogin : IdentityUserLogin<int>
{
    public User User { get; set; }
    public override int UserId { get; set; }
}

任何帮助将不胜感激。我知道我可能可以采取一种解决方法,例如为这些表手动指定映射,但我更愿意弄清楚如何使用迁移工具以及我的扩展身份类。

解决方法

  1. 您的 UserLogin 模型具有从 UserId 继承的 IdentityUserLogin 属性。

  2. 根据默认的Identity数据模型,IdentityUserIdentityUserLogin之间已经存在一对多的关系,并且UserId属性中的IdentityUserLogin Identity 用作此关系的外键。

  3. AspNetUserLogins 数据库是基于默认数据模型和您对这些模型所做的任何扩展生成的。因此,UserId 表已经有一个 AspNetUsers 列用作 UserId1 表的外键。

  4. 是否需要现有关系的导航属性取决于您。

现在,您已经添加了导航属性,但您没有告诉 EF 您希望这些导航基于现有关系。因此,EF 将其视为一种新的一对多关系,并在 AspNetUserLogins 表中创建一个新的外键列 OnModelCreating

protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity<User>(e => { e.HasMany(p => p.Logins) .WithOne(p => p.User) .HasForeignKey(p => p.UserId); // inherited from IdentityUserLogin }); } 方法中,只需告诉 EF 您添加的导航应基于现有的外键 -

 <button
            *ngIf="(element.account.status && (element.account.status === 'DRAFT') || (element.account.status === 'PENDING') || (element.account.status === 'REVERT') || (element.account.status === 'REVIEW')); else addDisabled"
            id="add-account" mat-icon-button (click)="openDialog(element.accountType)">
            <img src="../../../../assets/add.svg" />
 </button>
 <ng-template #addDisabled>
            <button id="add-account" mat-icon-button [disabled]="true">
              <img class="intro" src="../../../../svgs/add-disabled.svg" />
            </button>
 </ng-template>
,

IdentityUserLogin 已经有一个 UserId 属性,它将变成 UserId columnn IdentityUserLogin SourceCode

当您将 User 属性添加到 UserLogin 时,EF 还会添加一个 UserId 属性(就像您在问题中指出的那样)。 然后将其转换为通常名为 UserId

的列

为了防止重复的属性名称,Ef 必须通过添加后缀 UserId

使 your 1 不同

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...