В вашем UserBook
классе модели вы использовали UserId
типа int
для ApplicationUser
, но в вашем ApplicationUser
классе модели вы наследуете IdentityUser
, где первичный ключ Id
имеет тип string
по умолчанию это означает, что ваш ApplicationUser
s Id
имеет тип string
.Таким образом, в таблице Foreignkey
будет * несоответствие типа первичного ключа.
Solution-1: Если у вас нет проблем с сохранением первичного ключа ApplicationUser
Id
типа string
, затем просто измените тип UserId
на строку в UserBook
классе модели следующим образом:
public class UserBook
{
public string UserId { get; set; }
public ApplicationUser ApplicationUser { get; set; }
public int BookId { get; set; }
public Book Book { get; set; }
}
Solution-2: Если вы хотитеИзмените первичный ключ ApplicationUser
Id
со значения по умолчанию string
type на int
, затем укажите тип ключа как int
при наследовании IdentityUser
следующим образом:
public class ApplicationUser : IdentityUser<int>
{
public ICollection<UserBook> UserBooks { get; set; }
}
Теперь необходимо внести изменения в метод ConfigureServices
класса Startup следующим образом:
services.AddDefaultIdentity<IdentityUser<int>>() // here replace `IdentityUser` with `IdentityUser<int>`
.AddDefaultUI()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
Теперь, наконец, конфигурация вашей модели (как для Solution-1, так и для Solution-2) , используяFluent Api
должно быть следующим:
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);
}