扩展ASP.NET标识角色:IdentityRole不是当前上下文模型的一部分

我正在尝试在我的MVC5应用程序中使用新的ASP.NET标识,特别是我正在尝试将ASP.NET标识集成到现有数据库中。 我已经阅读了有关DB First和ASP.NET Identity的问题/答案,并且遵循了所有建议我仍然无法将角色添加到我的数据库中,尽管添加用户没有任何问题。 这是我的代码:

var context = new PayrollDBEntities(); var roleManager = new RoleManager(new RoleStore(context)); bool roleExists = roleManager.RoleExists(roleDto.Name); if (roleExists){ return false; } var role = new AspNetRole(roleDto.Name){ Name = roleDto.Name, }; IdentityResult result = roleManager.Create(role);//Getting exception here 

在代码的最后一行,我得到类型'System.InvalidOperationException': The entity type IdentityRole is not part of the model for the current context.的exception'System.InvalidOperationException': The entity type IdentityRole is not part of the model for the current context.

这是我的背景:

 public partial class PayrollDBEntities : IdentityDbContext { public PayrollDBEntities() : base("name=PayrollDBEntities") { } public virtual DbSet AspNetRoles { get; set; } public virtual DbSet AspNetUserClaims { get; set; } public virtual DbSet AspNetUserLogins { get; set; } public virtual DbSet AspNetUsers { get; set; } ...... } 

我的AspNetUserAspNetRole类分别来自IdentityUserIdentityRole ,但我仍然得到了这个例外。 这是我的数据库图:

在此处输入图像描述

任何帮助将不胜感激。

您必须在创建用户存储期间指定使用AspNetRole而不是IdentityRole。 您可以通过使用带有6个类型参数的UserStore类来实现此目的:

 new UserStore(new PayrollDBEntities()); 

这表示用户管理器创建时也会发生更改。 以下是有关创建所需实例的简化示例:

 public class AspNetUser : IdentityUser { /*customization*/ } public class AspNetRole : IdentityRole { /*customization*/ } public class PayrollDBEntities : IdentityDbContext //or : IdentityDbContext  { } public class Factory { public IdentityDbContext DbContext { get { return new PayrollDBEntities(); } } public UserStore UserStore { get { return new UserStore(DbContext); } } public UserManager UserManager { get { return new UserManager(UserStore); } } public RoleStore RoleStore { get { return new RoleStore(DbContext); } } public RoleManager RoleManager { get { return new RoleManager(RoleStore); } } } 

在尝试以干净的方式工作几天之后,我得出的结论是,如果您首先使用数据库并希望将ASP.NET身份集成到您的应用程序中,那么这是迄今为止最简单,最干净的解决方案是通过重写ASP.NET标识来创建自己的成员资格提供程序。 它实际上非常简单,到目前为止,我已经按照自己的喜好实现了UserStoreRoleStore 。 我在我的数据库中添加了特定于我的域的列/关系,每当我创建用户或角色时,我通过添加所需的关系来处理我的数据库提交。 我的UserStore实现与此非常相似。 我的RoleStore实现是这样的:

 public class ApplicationRoleStore : IRoleStore { private PayrollDBEntities _context; public ApplicationRoleStore() { } public ApplicationRoleStore(PayrollDBEntities database) { _context = database; } public Task CreateAsync(ApplicationRoleDTO role) { if (role == null) { throw new ArgumentNullException("RoleIsRequired"); } var roleEntity = ConvertApplicationRoleDTOToAspNetRole(role); _context.AspNetRoles.Add(roleEntity); return _context.SaveChangesAsync(); } public Task DeleteAsync(ApplicationRoleDTO role) { var roleEntity = _context.AspNetRoles.FirstOrDefault(x => x.Id == role.Id); if (roleEntity == null) throw new InvalidOperationException("No such role exists!"); _context.AspNetRoles.Remove(roleEntity); return _context.SaveChangesAsync(); } public Task FindByIdAsync(string roleId) { var role = _context.AspNetRoles.FirstOrDefault(x => x.Id == roleId); var result = role == null ? null : ConvertAspNetRoleToApplicationRoleDTO(role); return Task.FromResult(result); } public Task FindByNameAsync(string roleName) { var role = _context.AspNetRoles.FirstOrDefault(x => x.Name == roleName); var result = role == null ? null : ConvertAspNetRoleToApplicationRoleDTO(role); return Task.FromResult(result); } public Task UpdateAsync(ApplicationRoleDTO role) { return _context.SaveChangesAsync(); } public void Dispose() { _context.Dispose(); } private ApplicationRoleDTO ConvertAspNetRoleToApplicationRoleDTO(AspNetRole aspRole) { return new ApplicationRoleDTO{ Id = aspRole.Id, EnterpriseId = aspRole.EnterpriseId, Name = aspRole.Name }; } private AspNetRole ConvertApplicationRoleDTOToAspNetRole(ApplicationRoleDTO appRole) { return new AspNetRole{ Id = appRole.Id, EnterpriseId = appRole.EnterpriseId, Name = appRole.Name, }; } } 

和我的ApplicationRoleDTO:

 public class ApplicationRoleDTO : IRole { public ApplicationRoleDTO() { Id = Guid.NewGuid().ToString(); } public ApplicationRoleDTO(string roleName) : this() { Name = roleName; } public string Id { get; set; } public string Name { get; set; } public Guid EnterpriseId { get; set; } } 

我还发现这两篇文章非常有帮助:

ASP.NET身份的自定义存储提供程序概述

实现自定义MySQL ASP.NET身份存储提供程序

我将在这里解释代码示例:)。

诀窍是,它们已经在IdentityDbContext中(AspNetRoles,AspNetUserClaims,AspNetUsers,….)

在IdentityModel中,您将看到ApplicationUser在顶部为空。 如果要自定义这些用户或角色,只需在此处添加属性,然后通过控制台更新数据库

我的上下文的例子

 public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext() : base("DefaultConnection") { } public DbSet Requests { get; set; } public DbSet Reservations { get; set; } public DbSet PriceTypes { get; set; } public DbSet Products { get; set; } public DbSet Prices { get; set; } public DbSet Posts { get; set; } public DbSet Counts { get; set; } public DbSet Invoices { get; set; } public DbSet InvoiceLines { get; set; } ... } 

所以这里没有定义应用程序用户,但我确实为它添加了更多属性,例如:

 public class ApplicationUser : IdentityUser { public string FirstName { get; set; } public string LastName { get; set; } public string GroupName { get; set; } public string Email { get; set; } [StringLength(15)] public string Phone { get; set; } public string Remark { get; set; } public DateTime? BirthDate { get; set; } public DateTime ValidFrom { get; set; } public DateTime ValidUntil { get; set; } public string Street { get; set; } public string ZipCode { get; set; } public string City { get; set; } public virtual ICollection Requests { get; set; } } 

我知道这是一个老问题,但是万一其他人在修改asp身份以使用数字主键(int / long)而不是Identity Roles的默认字符串时,很难添加角色/用户,所以如果您已将IdentityModels.cs中的IdentityUserRole更改为以下内容:

 public class Role : IdentityRole { public Role() { } public Role(string name) { Name = name; } } 

在构造RoleManager时,您必须使用类Role而不是默认的IdentityRole ,因此您的代码应如下所示:

 public static void RegisterUserRoles() { ApplicationDbContext context = new ApplicationDbContext(); var RoleManager = new RoleManager(new RoleStore(context)); if (!RoleManager.RoleExists("Administrador")) { var adminRole = new Role { Name = "Administrador", }; RoleManager.Create(adminRole); } } 

因此,这应该正确填充您的数据库,我认为所有经验丰富的ASP程序员已经知道这一点,但对于其他人来说,这可能需要一些时间来弄清楚。

我通过更改web.config DefaultConnection connectionString属性来解决此问题,因此它指向新的SQLServer数据库