Страницы

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

четверг, 26 декабря 2019 г.

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

#c_sharp #net #aspnet #aspnet_mvc #entity_framework


В приложении должно присутствовать несколько типов учётных записей пользователей
и у каждой должен быть свой набор полей. Одним из вариантов я вижу создание иерархии
наследования:

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 работать с этой иерархией и возвращать сущность пользователя
нужного мне типа?
    


Ответы

Ответ 1



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"); });

Ответ 2



Identity научить можно, но вот возвращаться вам всегда будет IUser. Я бы рекомендовал отказаться от наследования и использовать композицию. Также, на мой взгляд, не нужно мешать identity и ваш domen. Так у вас будет: public class ApplicationUser : IUser { public async Task GenerateUserIdentityAsync(UserManager manager) { var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); return userIdentity; } public string Id { get; private set; } public string UserName { get; set; } } public class SchoolUser { public virtual ApplicationUser ApplicationUser { get; set; } public string ApplicationUserId { get; set; } 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 class StudentUser : SchoolUser { public TeachingType TeachingType { get; set; } public int Grade { get; set; } } public class TeacherUser : SchoolUser { public bool IsConfirmed { get; set; } public List Subjects { get; set; } } Кроме того, лучше всего будет написать свой "Identity" слой. Как это сделать, можете посмотреть здесь http://weblogs.asp.net/imranbaloch/a-simple-implementation-of-microsoft-aspnet-identity

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

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