c # asp.net идентификационные данные и пользовательские роли

#c# #asp.net-core #entity-framework-core #asp.net-identity

#c# #asp.net-ядро #сущность-основа-ядро #asp.net-идентификатор

Вопрос:

Я думаю, что я просто делаю здесь что-то глупое. Я использовал code first entity framework с asp.net идентификация, и я настраиваю пользовательского пользователя следующим образом:

 public class User : IdentityUser, IKey<string>
{
    [MaxLength(100)] public string JobTitle { get; set; }
    [MaxLength(100)] public string Image { get; set; }
    [MaxLength(100)] public string FirstName { get; set; }
    [MaxLength(100)] public string LastName { get; set; }
}
  

затем я обновил свой DbContext , чтобы соответствовать:

 protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    // Customize the ASP.NET Identity model and override the defaults if needed.
    // For example, you can rename the ASP.NET Identity table names and more.
    // Add your customizations after calling base.OnModelCreating(builder);

    builder.Entity<User>(m => m.ToTable("Users"));
    builder.Entity<IdentityRole>(m => m.ToTable("Roles"));
    builder.Entity<IdentityRoleClaim<string>>(m => m.ToTable("RoleClaims"));
    builder.Entity<IdentityUserClaim<string>>(m => m.ToTable("UserClaims"));
    builder.Entity<IdentityUserLogin<string>>(m => m.ToTable("UserLogins"));
    builder.Entity<IdentityUserRole<string>>(m => m.ToTable("UserRoles"));
    builder.Entity<IdentityUserToken<string>>(m => m.ToTable("UserTokens"));
}
  

Все работает, и таблицы были созданы успешно.
Теперь я хочу сделать то же самое для ролей, за исключением того, что на этот раз мне не нужны дополнительные столбцы (здесь важен интерфейс), поэтому я создаю новый Role класс:

 public class Role: IdentityRole, IKey<string>
{
}
  

Затем я изменил свой OnModelCreating метод на этот:

 protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);
    // Customize the ASP.NET Identity model and override the defaults if needed.
    // For example, you can rename the ASP.NET Identity table names and more.
    // Add your customizations after calling base.OnModelCreating(builder);

    builder.Entity<User>(m => m.ToTable("Users"));
    builder.Entity<Role>(m => m.ToTable("Roles"));
    builder.Entity<IdentityRoleClaim<string>>(m => m.ToTable("RoleClaims"));
    builder.Entity<IdentityUserClaim<string>>(m => m.ToTable("UserClaims"));
    builder.Entity<IdentityUserLogin<string>>(m => m.ToTable("UserLogins"));
    builder.Entity<IdentityUserRole<string>>(m => m.ToTable("UserRoles"));
    builder.Entity<IdentityUserToken<string>>(m => m.ToTable("UserTokens"));
}
  

Единственная строка, которая изменилась, была builder.Entity<Role>(m => m.ToTable("Roles")); .
Когда я запускаю add-migration RoleChange , я ожидал, что со времени моей последней миграции ничего не изменилось, но вместо этого я получаю эту ошибку:

Тип сущности ‘Role’ не может быть сопоставлен с таблицей, поскольку он является производным от ‘IdentityRole’. В таблицу могут быть сопоставлены только базовые типы сущностей.

Кто-нибудь знает, почему? Я не понимаю, почему User работает, но Role не будет….


Вот полный контекст:

 public class DatabaseContext : IdentityDbContext<User>
{
    public DbSet<Claim> Claims { get; set; }

    /// <summary>
    /// For testing only
    /// </summary>
    public DatabaseContext()
    {

    }

    // ReSharper disable once SuggestBaseTypeForParameter
    public DatabaseContext(DbContextOptions<DatabaseContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
        // Customize the ASP.NET Identity model and override the defaults if needed.
        // For example, you can rename the ASP.NET Identity table names and more.
        // Add your customizations after calling base.OnModelCreating(builder);

        builder.Entity<User>(m => m.ToTable("Users"));
        builder.Entity<Role>(m => m.ToTable("Roles"));
        builder.Entity<IdentityRoleClaim<string>>(m => m.ToTable("RoleClaims"));
        builder.Entity<IdentityUserClaim<string>>(m => m.ToTable("UserClaims"));
        builder.Entity<IdentityUserLogin<string>>(m => m.ToTable("UserLogins"));
        builder.Entity<IdentityUserRole<string>>(m => m.ToTable("UserRoles"));
        builder.Entity<IdentityUserToken<string>>(m => m.ToTable("UserTokens"));
    }
}
  

Комментарии:

1. Не могли бы вы, пожалуйста, поделиться своим DataContext классом?

2. это очень просто. Но я добавил это

3. Попробуйте удалить все миграции и создать новую с нуля. Будет ли это работать?

4. добавьте свою role модель IdentityDbContext<User> следующим образом: IdentityDbContext<User, Role, string> string — это тип ключа, который требуется здесь

5. Не могли бы вы показать соответствующую часть вашего Startup ? Где вы добавляете и настраиваете идентификатор. Вам понадобится что-то вроде этого: services.AddIdentity<User, Role>(options => /* etc... */ )

Ответ №1:

То, что вы сделали, правильно, вам просто нужно обновить эту строку

 public class DatabaseContext : IdentityDbContext<User>
  

как показано ниже :

 public class DatabaseContext : IdentityDbContext<User, Role, string>
  

Комментарии:

1. Да, это то волшебство, которое требуется. Если вам интересно, для моей собственной справки я создал репозиторий с некоторыми из этих распространенных настроек.