在 AspNetRoles 中添加自定义列会导致无效的列名鉴别器
Add custom column in AspNetRoles results in Invalid Column Name Discriminator
我正在使用 ASP.NET MVC5 和 Identity 2 框架,数据库优先
我正在尝试通过添加名为 MyCustomColumn
的列来自定义 AspNetRoles
但是,我的应用程序崩溃了,因为:
Invalid Column Name Discriminator
SO 和网络上的其他地方有很多资源,但大多数都是使用 CodeFirst 方法,我无法在我的应用程序中使用它们。
如何处理?
好的,因为我花了几个小时来寻找解决方案,所以我 post 在这里,如果它可以帮助其他人的话。
首先,在 AspNetRoles
中创建您的自定义列 AND 一个名为 Discriminator
的列(这是一个 nvarchar(max)
)。更新您的 .edmx
然后,我们必须创建一个继承自IdentityRole
的class。我们将使用此 class 访问我们刚刚创建的自定义列:
在模型文件夹中
public ApplicationRole()
: base() { }
public ApplicationRole(string name, long myCustomValue)
: base(name)
{
MyCustomValue = myCustomValue;
}
public virtual long MyCustomValue { get; set; }
然后,让我们创建一个继承自 RoleManager<ApplicationRole>
的 class。
我将它放在 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
class.
现在我们必须在启动时注册我们的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();
其实,none这个是有必要的。您很可能无法更新您的上下文以继承自 IdentityDbContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim>
,而不是默认的 IdentityDbContext<TUser>
。由于您没有将自定义角色实体作为 TRole
类型参数传递,因此上下文改为使用 IdentityRole
作为 class 类型。然后它为 IdentityRole
创建一个 table,看到您的自定义角色继承自 IdentityRole
,因此添加鉴别器列,以便它可以区分 [=15= 的实例之间的差异] 和您的自定义角色,在数据库中(单个 table 继承是 EF 使用的默认策略)。
这在技术上 会起作用,但您的自定义角色永远不会被实际使用。使用正确的通用抽象上下文 class,你会没事的。
为了它的价值,你也应该去掉 EDMX 的东西。它已被弃用,有错误且不必要。尽管名称如此,"Code First" 可用于现有数据库或创建新数据库。
不要
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
DO
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
我正在使用 ASP.NET MVC5 和 Identity 2 框架,数据库优先
我正在尝试通过添加名为 MyCustomColumn
的列来自定义AspNetRoles
但是,我的应用程序崩溃了,因为:
Invalid Column Name Discriminator
SO 和网络上的其他地方有很多资源,但大多数都是使用 CodeFirst 方法,我无法在我的应用程序中使用它们。
如何处理?
好的,因为我花了几个小时来寻找解决方案,所以我 post 在这里,如果它可以帮助其他人的话。
首先,在 AspNetRoles
中创建您的自定义列 AND 一个名为 Discriminator
的列(这是一个 nvarchar(max)
)。更新您的 .edmx
然后,我们必须创建一个继承自IdentityRole
的class。我们将使用此 class 访问我们刚刚创建的自定义列:
在模型文件夹中
public ApplicationRole()
: base() { }
public ApplicationRole(string name, long myCustomValue)
: base(name)
{
MyCustomValue = myCustomValue;
}
public virtual long MyCustomValue { get; set; }
然后,让我们创建一个继承自 RoleManager<ApplicationRole>
的 class。
我将它放在 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
class.
现在我们必须在启动时注册我们的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();
其实,none这个是有必要的。您很可能无法更新您的上下文以继承自 IdentityDbContext<TUser, TRole, TKey, TUserLogin, TUserRole, TUserClaim>
,而不是默认的 IdentityDbContext<TUser>
。由于您没有将自定义角色实体作为 TRole
类型参数传递,因此上下文改为使用 IdentityRole
作为 class 类型。然后它为 IdentityRole
创建一个 table,看到您的自定义角色继承自 IdentityRole
,因此添加鉴别器列,以便它可以区分 [=15= 的实例之间的差异] 和您的自定义角色,在数据库中(单个 table 继承是 EF 使用的默认策略)。
这在技术上 会起作用,但您的自定义角色永远不会被实际使用。使用正确的通用抽象上下文 class,你会没事的。
为了它的价值,你也应该去掉 EDMX 的东西。它已被弃用,有错误且不必要。尽管名称如此,"Code First" 可用于现有数据库或创建新数据库。
不要
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
DO
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>