在AspNetRoles中添加自定义列会导致无效的列名称识别符

时间:2016-09-26 14:31:15

标签: asp.net-mvc asp.net-mvc-5 asp.net-identity-2 asp.net-roles discriminator

我正在使用带有 Identity 2 框架的ASP.NET MVC5,数据库优先

我正在尝试通过添加名为 MyCustomColumn

的列来自定义AspNetRoles

然而,我的应用程序崩溃是因为:

  

无效的列名称识别器

网上有很多SO和其他网站的资源,但大多数都使用CodeFirst方法,我不能在我的应用中使用它们。

如何处理?

2 个答案:

答案 0 :(得分:5)

实际上,这都不是必需的。很可能您无法更新您的上下文以继承IdentityDbContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim>,而不是默认的IdentityDbContext<TUser>。由于您未将自定义角色实体作为TRole类型参数传递,因此上下文使用IdentityRole作为类类型。然后它为IdentityRole创建一个表,看到您的自定义角色继承自IdentityRole,因此添加了Discriminator列,以便它可以告诉IdentityRole的实例和您的自定义之间的不同角色,在数据库中(单表继承是EF使用的默认策略)。

这将技术上工作,但您的自定义角色将永远不会被使用。使用正确的通用抽象上下文类,你会没事的。

对于它的价值,你也应该取消EDMX的东西。它已被弃用,错误和不必要。尽管名称如此,“Code First”可以与现有数据库一起使用,也可以创建一个新数据库。

<强>不

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>

<强> DO

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>

答案 1 :(得分:2)

好的,因为我花了几个小时才找到解决方案,我在这里发布,如果它可以帮助其他人。

首先,在AspNetRoles中,创建自定义列 AND 一个名为Discriminator的列(nvarchar(max))。更新您的.edmx

然后,我们必须创建一个继承自IdentityRole的类。我们将使用此类访问我们刚刚创建的自定义列:

在模型文件夹

public ApplicationRole()
        : base() { }

    public ApplicationRole(string name, long myCustomValue)
        : base(name)
    {
        MyCustomValue = myCustomValue;
    }

    public virtual long MyCustomValue { get; set; }


然后,让我们创建一个继承自RoleManager<ApplicationRole>的类。 我将它放在IdentityConfig.cs中,但也许将它放在别处是最好的做法...... 有关信息,我受到this blog重新实现RoleStore和ApplicationRoleManager 段落的启发

public class ApplicationRoleManager : RoleManager<ApplicationRole>
{
    public ApplicationRoleManager(
        IRoleStore<ApplicationRole, string> roleStore)
        : base(roleStore)
    {
    }
    public static ApplicationRoleManager Create(
        IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
    {
        return new ApplicationRoleManager(
            new RoleStore<ApplicationRole>(context.Get<ApplicationDbContext>()));
    }
}

ApplicationRoleManager有一个构造函数,它调用我们之前创建的ApplicationRole类。

现在我们必须在启动时注册我们的ApplicationRoleManager,因此我们必须在其他人CreatePerOwinContext之后添加此行

在App_Start \ Startup.auth.cs,ConfigureAuth(IAppBuilder app)方法

app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);


所以现在我们可以使用我们的ApplicationRoleManager,正确实例化了

var rm = new ApplicationRoleManager(new RoleStore<ApplicationRole>(new ApplicationDbContext()));

然后按我们的意愿使用它

var roleName = rm.FindByName("Admin");
string myCustomData = roleName.CustomData.ToString();