Страницы

Поиск по вопросам

четверг, 29 ноября 2018 г.

Использование нескольких типов пользователей в ASP.NET Identity

В приложении должно присутствовать несколько типов учётных записей пользователей и у каждой должен быть свой набор полей. Одним из вариантов я вижу создание иерархии наследования:
public class ApplicationUser : IdentityUser { public string Name { get; set; } public string Surname { get; set; } public IImage AvatarImage { get; set; } public bool IsBlocked { get; set; } public School School { get; set; }
public async Task GenerateUserIdentityAsync(UserManager manager) { var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); return userIdentity; } }
public class StudentUser : ApplicationUser { public TeachingType TeachingType { get; set; } public int Grade { get; set; } }
public class TeacherUser : ApplicationUser { public bool IsConfirmed { get; set; } public List Subjects { get; set; } }
Контекст я вижу таким:
public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext() : base("DefaultConnection", throwIfV1Schema: false) { }
public DbSet TeacherUsers { get; set; } public DbSet StudentUsers { get; set; } }
Есть ли способ научить Identity работать с этой иерархией и возвращать сущность пользователя нужного мне типа?


Ответ

Identity в вашем случае использует самый обычный Entity Framework для хранения учетных записей пользователей - а Entity Framework всегда имел такую возможность.
Только контекст вы привели неправильный.
Независимо от способа хранения, DbSet должен быть один на иерархию и в нем должен храниться базовый класс.
А способов хранения - три:
Table per Hierarchy (TPH) - все свалено в одну таблицу. Table per Type (TPT) - на каждый класс по таблице, их первичные ключи объединены отношениями вида 1 - (0..1). Table per Concrete class (TPC) - по таблице на каждый неабстрактный класс. Но DbSet при этом все равно один!
Для создания БД первого типа просто добавьте DbSet с базовым типом в контекст - все потомки будут свалены в ту же таблицу автоматически.
Если вам больше нравится второй тип - добавьте потомкам атрибут Table. Или перегрузите метод OnModelCreating, указав там примерно следующее:
modelBuilder.Entity().ToTable("TeacherUsers"); modelBuilder.Entity().ToTable("StudentUsers");
Ну а если больше всего нравится третий тип - используйте вот такую конструкцию в том же методе:
modelBuilder.Entity().Map(m => { m.MapInheritedProperties(); m.ToTable("TeacherUsers"); });
modelBuilder.Entity().Map(m => { m.MapInheritedProperties(); m.ToTable("StudentUsers"); });

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

Отправить комментарий