具有一对多关系的自定义身份用户 class 在数据库中创建额外的列
Custom Identity User class with one-to-many relationship creates extra column in database
我在 .NET 5
上使用 ASP.NET Core Identity
和 Entity Framework Core
,使用代码优先方法和 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)
{
}
}
然而,当我 运行 迁移时,它生成的表看起来像这样 -
请注意,已创建一个额外的列 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; }
}
如有任何帮助,我们将不胜感激。我知道我可能可以做一个解决方法,比如为这些表手动指定映射,但我宁愿弄清楚如何使用迁移工具和我的扩展身份 类.
IdentityUserLogin
已经有一个 UserId 属性 将变成 UserId 列
IdentityUserLogin SourceCode
当您将用户 属性 添加到 UserLogin 时,EF 也会添加一个 UserId 属性 (就像您在问题中指出的那样)。
然后将其变成 通常 的列 UserId
为了防止重复的 属性 名称 Ef 必须通过添加后缀 1
[=15= 使 您的 UserId
不同]
您的 UserLogin
模型有一个 UserId
属性 继承自 IdentityUserLogin
。
根据默认的Identity
数据模型,IdentityUser
和IdentityUserLogin
之间已经存在一对多的关系,而UserId
IdentityUserLogin
中的 属性 作为此关系的外键。
Identity
数据库是根据默认数据模型和您对这些模型所做的任何扩展生成的。因此,AspNetUserLogins
table 已经有一个 UserId
列用作 AspNetUsers
table.
的外键
是否需要现有关系的导航属性取决于您。
现在,您已经添加了导航属性,但您没有告诉 EF 您希望这些导航基于现有关系。因此,EF 将此视为新的一对多关系,并在 AspNetUserLogins
table.
中创建新的外键列 UserId1
在 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
});
}
我在 .NET 5
上使用 ASP.NET Core Identity
和 Entity Framework Core
,使用代码优先方法和 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)
{
}
}
然而,当我 运行 迁移时,它生成的表看起来像这样 -
请注意,已创建一个额外的列 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; }
}
如有任何帮助,我们将不胜感激。我知道我可能可以做一个解决方法,比如为这些表手动指定映射,但我宁愿弄清楚如何使用迁移工具和我的扩展身份 类.
IdentityUserLogin
已经有一个 UserId 属性 将变成 UserId 列
IdentityUserLogin SourceCode
当您将用户 属性 添加到 UserLogin 时,EF 也会添加一个 UserId 属性 (就像您在问题中指出的那样)。
然后将其变成 通常 的列 UserId
为了防止重复的 属性 名称 Ef 必须通过添加后缀 1
[=15= 使 您的 UserId
不同]
您的
UserLogin
模型有一个UserId
属性 继承自IdentityUserLogin
。根据默认的
Identity
数据模型,IdentityUser
和IdentityUserLogin
之间已经存在一对多的关系,而UserId
IdentityUserLogin
中的 属性 作为此关系的外键。
的外键Identity
数据库是根据默认数据模型和您对这些模型所做的任何扩展生成的。因此,AspNetUserLogins
table 已经有一个UserId
列用作AspNetUsers
table.是否需要现有关系的导航属性取决于您。
现在,您已经添加了导航属性,但您没有告诉 EF 您希望这些导航基于现有关系。因此,EF 将此视为新的一对多关系,并在 AspNetUserLogins
table.
UserId1
在 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
});
}