[英]ASP Net Core: add many to many relationship with IdentityUser
我需要在ASP网络核心中与UserIdentity添加多对多关系(即:一个用户可以有很多书,而一本书可以有很多用户所有者)
我有这本书课:
public class Book
{
public int Id { get; set; }
}
我扩展了UserIdentity类:
public class ApplicationUser : IdentityUser
{
public ICollection<UserBook> UserBooks { get; set; }
}
我已经创建了联接表,但是我不知道如何引用identityuser ID
public class UserBook
{
public int UserId { get; set; }
public ApplicationUser ApplicationUser { get; set; }
public int BookId { get; set; }
public Book Book { get; set; }
}
如何正确创建identityuser表和另一个表之间的多对多关系?
谢谢
在您的UserBook
模型类中,您已经为ApplicationUser
使用了int
类型的UserId
,但是在您的ApplicationUser
模型类中,您继承了IdentityUser
,其中默认情况下,主键Id
为string
类型,这意味着您的ApplicationUser
的Id
类型为string
类型。 于是就有了主键类型不匹配Foreignkey
的UserBook
表。
解决方案1:如果可以毫无问题地将ApplicationUser
的主键Id
保持为string
类型,则只需在UserBook
模型类中将UserId
类型更改为string UserBook
,如下所示:
public class UserBook
{
public string UserId { get; set; }
public ApplicationUser ApplicationUser { get; set; }
public int BookId { get; set; }
public Book Book { get; set; }
}
解决方案2:如果要将ApplicationUser
的主键Id
从默认string
类型更改为int
,则在继承IdentityUser
时将键类型指定为int
,如下所示:
public class ApplicationUser : IdentityUser<int>
{
public ICollection<UserBook> UserBooks { get; set; }
}
现在,您必须在Startup类的ConfigureServices
方法中进行如下更改:
services.AddDefaultIdentity<IdentityUser<int>>() // here replace `IdentityUser` with `IdentityUser<int>`
.AddDefaultUI()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
现在,最终使用Fluent Api
的模型配置(针对Solution-1和Solution-2)应该如下:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<UserBook>()
.HasKey(ub => new { ub.UserId, ub.BookId });
modelBuilder.Entity<UserBook>()
.HasOne(ub => ub.ApplicationUser)
.WithMany(au => au.UserBooks)
.HasForeignKey(ub => ub.UserId);
modelBuilder.Entity<UserBook>()
.HasOne(ub => ub.Book)
.WithMany() // If you add `public ICollection<UserBook> UserBooks { get; set; }` navigation property to Book model class then replace `.WithMany()` with `.WithMany(b => b.UserBooks)`
.HasForeignKey(ub => ub.BookId);
}
简单的public string ApplicationUserId { get; set; }
public string ApplicationUserId { get; set; }
ApplicationUser的默认键类型为string
。
如果您确实想使用int,则只需执行以下操作:
public class ApplicationUser : IdentityUser<int>
确保在您的DbContext中声明此关系。
这是一个示例:
entityTypeBuilder.HasKey(pcp => new { pcp.CurrencyPairId, pcp.IsMain })
.HasName("PartialCurrencyPair_CK_CurrencyPairId_IsMain");
entityTypeBuilder.HasOne(pcp => pcp.Currency).WithMany(c => c.PartialCurrencyPairs)
.HasForeignKey(pcp => pcp.CurrencyId)
.HasConstraintName("PartialCurrencyPairs_Currency_Constraint");
entityTypeBuilder.HasOne(pcp => pcp.CurrencyPair).WithMany(cp => cp.PartialCurrencyPairs)
.HasForeignKey(pcp => pcp.CurrencyPairId)
.HasConstraintName("PartialCurrencyPairs_CurrencyPair_Constraint");
编辑
您不必与基类(IdentityUser)一起显式定义泛型。 您只需执行以下操作:
services.AddIdentity<ApplicationUser, Role>()
.AddEntityFrameworkStores<NozomiAuthContext>()
.AddDefaultTokenProviders();
假定Role和ApplicationUser共享相同的string
键类型,它们分别是IdentityRole和IdentityUser的重载。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.