В таблице UserRole есть повторяющиеся столбцы, но с разными именами, что вызывает проблемы с проверкой ролей.

Мой проект использует Microsoft ASP.NET Identity Framework и до недавнего времени использовал версию 2.0 и работал правильно. Тогда я заметил, что в таблице UserRole есть 4 столбца, содержащие практически одни и те же данные:

введите здесь описание изображения

С момента обновления до 2.1 кажется, что второй набор [Null] остался, что, на мой взгляд, хорошо (я не могу найти, где были определены эти дополнительные столбцы).

modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaim");
        modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogin");
        modelBuilder.Entity<IdentityRole>().ToTable("Role");
        modelBuilder.Entity<ApplicationUser>().ToTable("User");

        modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
        modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
        modelBuilder.Entity<IdentityUserRole>().HasKey(r => new
        {
            r.RoleId, 
            r.UserId
        }).ToTable("UserRole");;

Проблема возникает, когда я иду использовать его:

await _manager.AddToRoleAsync(applicationUser.Id, "Admin");

вызов этого заполняет первые два столбца, тогда как:

var userRoles = await _manager.GetRolesAsync(applicationUser.Id);

кажется, запрашивает второй набор столбцов. Я знаю это, потому что они возвращают [Null], если я не скопирую и не вставлю значения из первых двух столбцов.

Я искал в своем коде что-нибудь, что могло бы пролить свет на это, но я признаю, что на данный момент я в полной растерянности.


person Incognos    schedule 23.10.2014    source источник
comment
может быть, ваша Entity Model или таблица должны быть обновлены, если вы вернулись в проект и вручную выполнили UPDATE... это единственное, что я могу придумать сразу..   -  person MethodMan    schedule 23.10.2014
comment
Вы имеете в виду команду «обновить базу данных» в powershell? если да, то да, я сделал несколько миграций с тех пор...   -  person Incognos    schedule 23.10.2014
comment
Столбцы ApplicationUser_Id и IdentityRole_Id не должны быть в этой таблице. Вам нужно настроить свои модели/dbContext, чтобы удалить эти столбцы.   -  person trailmax    schedule 23.10.2014
comment
Единственная расширяемая таблица — это таблица User. Из того, что я понял, похоже, что он не улавливает ключевые столбцы и создает дополнительные столбцы на основе исходных имен баз данных, на которые ссылаются. Как я уже упоминал, создание роли происходит в правильных столбцах, получение ролей, похоже, происходит из дополнительных столбцов. Где-то между INSERT и SELECT есть разрыв.   -  person Incognos    schedule 24.10.2014


Ответы (1)


После тщательного поиска я нашел это Авторизация и GetRoles не работает в публикации ASP.NET Identity. Это в сочетании с некоторым редактированием миграции решило проблему.

Обобщить:

я добавил

 base.OnModelCreating(modelBuilder);

в мой файл контекста и отредактировал часть генерации модели

        modelBuilder.Entity<IdentityUserClaim>().ToTable("UserClaim");
        modelBuilder.Entity<IdentityUserLogin>().ToTable("UserLogin");
        modelBuilder.Entity<IdentityRole>().ToTable("Role");
        modelBuilder.Entity<ApplicationUser>().ToTable("User");
        modelBuilder.Entity<IdentityUserRole>().ToTable("UserRole");

        //modelBuilder.Entity<IdentityUserLogin>().HasKey<string>(l => l.UserId);
        //modelBuilder.Entity<IdentityRole>().HasKey<string>(r => r.Id);
        //modelBuilder.Entity<ApplicationUser>().HasMany<IdentityUserRole>(u => u.Roles);
        //modelBuilder.Entity<IdentityUserRole>().HasKey(r => new
        //{
        //    r.RoleId, 
        //    r.UserId
        //});

Ваш код миграции пытается удалить некоторые столбцы и переименовать другие, поэтому вместо удаления и переименования я заставил его удалить столбцы, которые он собирался переименовать, и сохранить ранее существовавшие столбцы. Чтобы удалить уже существующие столбцы, вам также придется удалить внешние ключи. Мне также пришлось предотвратить повторное создание первичных ключей.

        DropIndex("dbo.UserClaim", new[] { "ApplicationUser_Id" });
        DropIndex("dbo.UserLogin", new[] { "ApplicationUser_Id" });
        DropIndex("dbo.UserRole", new[] { "ApplicationUser_Id" });
        DropIndex("dbo.UserRole", new[] { "IdentityRole_Id" });
        DropForeignKey("FK_dbo_UserClaim_ApplicationUser_Id", "ApplicationUser_Id");
        DropForeignKey("FK_dbo_UserLogin_ApplicationUser_Id", "ApplicationUser_Id");
        DropForeignKey("FK_dbo_UserRole_ApplicationUser_Id", "ApplicationUser_Id");
        DropForeignKey("FK_dbo_UserRole_IdentityRole_Id", "Identity_Id");
        DropColumn("dbo.UserClaim", "ApplicationUser_Id");
        DropColumn("dbo.UserLogin", "ApplicationUser_Id");
        DropColumn("dbo.UserRole", "ApplicationUser_Id");
        DropColumn("dbo.UserRole", "IdentityRole_Id");
        //DropPrimaryKey("dbo.UserLogin");
        //DropPrimaryKey("dbo.UserRole");
        AlterColumn("dbo.User", "Email", c => c.String(maxLength: 256));
        AlterColumn("dbo.User", "UserName", c => c.String(nullable: false, maxLength: 256));
        AlterColumn("dbo.UserClaim", "UserId", c => c.String(nullable: false, maxLength: 128));
        AlterColumn("dbo.UserClaim", "UserId", c => c.String(nullable: false, maxLength: 128));
        AlterColumn("dbo.UserLogin", "LoginProvider", c => c.String(nullable: false, maxLength: 128));
        AlterColumn("dbo.UserLogin", "ProviderKey", c => c.String(nullable: false, maxLength: 128));
        AlterColumn("dbo.UserLogin", "UserId", c => c.String(nullable: false, maxLength: 128));
        AlterColumn("dbo.UserRole", "UserId", c => c.String(nullable: false, maxLength: 128));
        AlterColumn("dbo.UserRole", "RoleId", c => c.String(nullable: false, maxLength: 128));
        AlterColumn("dbo.Role", "Name", c => c.String(nullable: false, maxLength: 256));
        //AddPrimaryKey("dbo.UserLogin", new[] { "LoginProvider", "ProviderKey", "UserId" });
        //AddPrimaryKey("dbo.UserRole", new[] { "UserId", "RoleId" });
        CreateIndex("dbo.User", "UserName", unique: true, name: "UserNameIndex");
        CreateIndex("dbo.UserClaim", "UserId");
        CreateIndex("dbo.UserLogin", "UserId");
        CreateIndex("dbo.UserRole", "UserId");
        CreateIndex("dbo.UserRole", "RoleId");
        CreateIndex("dbo.Role", "Name", unique: true, name: "RoleNameIndex");

Это был разочаровывающий опыт работы с Microsoft ASP.NET Identity, и я надеюсь, что вышеизложенное поможет кому-то сохранить еще несколько прядей волос.

person Incognos    schedule 24.10.2014