ASP Net Core: добавьте отношения многие ко многим с IdentityUser - PullRequest
0 голосов
/ 09 февраля 2019

мне нужно добавить отношение многие ко многим с UserIdentity в ядре asp net (то есть: у пользователя может быть много книг, а у книги может быть много владельцев)

У меня есть класс книги:

public class Book
{
    public int Id { get; set; }
}

Я расширил класс UserIdentity:

public class ApplicationUser : IdentityUser
{
    public ICollection<UserBook> UserBooks { get; set; }
}

Я создал таблицу соединений, но я не знаю, как ссылаться на идентификатор identityuser

public class UserBook
{
    public int UserId { get; set; }
    public ApplicationUser ApplicationUser { get; set; }
    public int BookId { get; set; }
    public Book Book { get; set; }
}

Какможет правильно создать связь «многие ко многим» между таблицей identityuser и другой таблицей?

Спасибо

Ответы [ 2 ]

0 голосов
/ 10 февраля 2019

В вашем 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);
}
0 голосов
/ 09 февраля 2019

Простой, 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 соответственно.

...