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

Cor*_*dez 4 c# entity-framework-core asp.net-core-identity entity-framework-core-migrations .net-5

ASP.NET Core IdentityEntity Framework Coreon一起使用.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)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

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

在此处输入图片说明

请注意,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; }
}
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激。我知道我可能可以做一个解决方法,比如为这些表手动指定映射,但我更喜欢弄清楚如何使用迁移工具和我的扩展身份类。

ati*_*yar 5

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

  2. 根据默认的Identity数据模型,已经有间的一种一对多的关系IdentityUser,并IdentityUserLogin与中,UserId房地产IdentityUserLogin作为这种关系的外键。

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

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

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

在该OnModelCreating方法中,只需告诉 EF 您添加的导航应基于现有的外键 -

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
    });
}
Run Code Online (Sandbox Code Playgroud)