UserRole表具有重复但名称不同的列,会导致角色检查问题

时间:2014-10-23 15:14:01

标签: c# asp.net asp.net-web-api asp.net-identity asp.net-identity-2

我的项目使用Microsoft ASP.NET Identity Framework,直到最近才使用版本2.0并正常工作。我当时注意到UserRole表有4列基本上保存相同的数据:

enter image description here

自从升级到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],除非我从前两列复制并粘贴值。

我一直在查看我的代码中的任何可能会对此有所了解的内容,但我承认在这一点上完全失去了。

1 个答案:

答案 0 :(得分:3)

经过一番明智的搜索后,我找到了这个Authorize and GetRoles doesn't work in 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");

这对微软ASP.NEt身份来说是一次令人沮丧的经历,我希望上面的内容可以帮助别人留下更多的头发。