Получить список ролей в EF Core 3.1 - PullRequest
0 голосов
/ 17 февраля 2020

Я хотел бы получить список всех ролей идентификации в ядре EF без использования UserManager / RoleManager. Я использую EF Core 3.1

В настоящее время в моем запуске:

services.AddIdentity<ApplicationUser, ApplicationRole>()
                .AddRoles<ApplicationRole>()
                .AddRoleManager<RoleManager<ApplicationRole>>()
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders(); //2FA

Тогда в моем контексте:

public partial class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
    {
        public ApplicationDbContext()
        {

        }

        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {

        }
        //....
    }

Мои ApplicationUser и ApplicationRole определены следующим образом:

public class ApplicationUser : IdentityUser
    {
        public virtual UserProfile UserProfile { get; set; }
    }

public class ApplicationRole : IdentityRole<String>
    {
        public int Hierarchy { get; set; }

        public ApplicationRole() : base()
        {

        }

        public ApplicationRole(string roleName) : base(roleName)
        {

        }
    }

Затем я просто пытаюсь вызвать любой контроллер, к которому я хочу обратиться (_context - это ApplicationDBContext):

var list = _context.Roles.ToArray();

В котором я получаю сообщение об ошибке:

Microsoft.Data.SqlClient.SqlException: 'Invalid column name 'ApplicationUserId'.'

Конечная цель - добавить ICollection of ApplicationRole в контекст ApplicationUser, поскольку EF Core, похоже, не поддерживает его. Я даже не могу выполнить соединение LINQ2Query от UserRoles до Role.

Любая помощь приветствуется, поскольку я потратил на это много часов.

1 Ответ

0 голосов
/ 17 февраля 2020

Хорошо, я наконец понял это, на случай, если кому-то интересно. Он не может правильно сопоставить роли, потому что ApplicationDBContext наследует неправильную конфигурацию модели IdentityDbContext. Для этого вы должны создать свой собственный класс, который наследует IdentityUserRole и реализовать соответствующий IdentityDBContext.

public partial class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserClaim<string>, ApplicationUserRole, IdentityUserLogin<string>, IdentityRoleClaim<string>, IdentityUserToken<string>>

Где ApplicationUser, ApplicationRole и ApplicationUserRole - ваши пользовательские классы.

public class ApplicationUserRole : IdentityUserRole<string>
{
    public ApplicationUserRole() : base()
    {

    }

    public virtual ApplicationUser User { get; set; }

    public virtual ApplicationRole Role { get; set; }
}

По какой-то причине EF пытался сгенерировать дополнительные столбцы "UserId1" и "RoleId1", чтобы избежать этого, я просто дал указание модели взять наследование IdentityUserRole, убедитесь, что ваши свойства Id соответствуют типу TKey.

Тогда я смог правильно оценить роли. Затем, чтобы получить отображение, я добавил следующее к ApplicationUser и ApplicationRole классам:

public virtual ICollection<ApplicationUserRole> UserRoles { get; set; }

Теперь, чтобы отобразить новые сущности, я добавил следующее в modelBuilder:

        modelBuilder.Entity<ApplicationUserRole>(entity =>
        {
            entity.HasOne(e => e.Role)
            .WithMany(e => e.UserRoles)
            .HasForeignKey(e => e.RoleId);

            entity.HasOne(e => e.User)
            .WithMany(e => e.UserRoles)
            .HasForeignKey(e => e.UserId);
        });

Все просто, не включайте никакую конфигурацию в ApplicationUser или ApplicationRole, поскольку IdentityDBContext будет обрабатывать это должным образом.

Теперь вы можете включать / присоединять цепочку, чтобы получить действительный класс ApplicationRole вместо IdentityRole<TKey>

Например:

var list = _context.Users.Include(u => u.UserRoles).ThenInclude(ur => ur.Role).ToList();

Подвести итог:

  1. Указать правильный экземпляр IdentityDBContext
  2. Создать сущность таблицы соединений ApplicationUserRole
  3. Настройка виртуальных свойств для сопоставления ApplicationUser и ApplicationRole
  4. Настройка виртуальных свойств для сопоставления RoleId и UserId, совпадающих с TKey
  5. Создание сопоставления сущностей с помощью построителя моделей, но оставление только сущности ApplicationUser / ApplicationRole
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...