Asp.net mvc 在扩展Asp.Net Identity 2中将角色分配给用户违反主键约束的错误';PK#dbo.AspNetUserRoles';
我为我的应用程序扩展了AspNetUserRoles,在Asp.net mvc 在扩展Asp.Net Identity 2中将角色分配给用户违反主键约束的错误';PK#dbo.AspNetUserRoles';,asp.net-mvc,asp.net-identity,asp.net-identity-2,user-roles,Asp.net Mvc,Asp.net Identity,Asp.net Identity 2,User Roles,我为我的应用程序扩展了AspNetUserRoles,在AspNetUserRoles表中添加了一个新的FK列ApplicationId。这背后的想法是允许同一用户在不同的应用程序中扮演相同或不同的角色。 在我尝试将同一角色添加到同一用户之前,一切似乎都正常,但对于我开始出现错误的不同应用程序: 违反主键约束“PK_dbo.AspNetUserRoles”。不能 在对象“dbo.AspNetUserRoles”中插入重复密钥 请任何人帮我解决这个问题 我的理想模型如下 public class
AspNetUserRoles
表中添加了一个新的FK列ApplicationId
。这背后的想法是允许同一用户在不同的应用程序中扮演相同或不同的角色。
在我尝试将同一角色添加到同一用户之前,一切似乎都正常,但对于我开始出现错误的不同应用程序:
违反主键约束“PK_dbo.AspNetUserRoles”。不能
在对象“dbo.AspNetUserRoles”中插入重复密钥
请任何人帮我解决这个问题
我的理想模型如下
public class ApplicationUser : IdentityUser
{
public virtual AspNetApplications AspNetApplication { get; set; }
public virtual AspNetUserRoles AspNetUserRoles { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
public DbSet<AspNetApplications> AspNetApplications { get; set; }
public DbSet<AspNetUserRoles> AspNetUserRoles { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
public class AspNetApplications
{
[Key]
public string ApplicationId { get; set; }
public string ApplicationName { get; set; }
}
public class AspNetUserRoles : IdentityUserRole
{
[Key]
public string ApplicationId { get; set; }
[ForeignKey("ApplicationId")]
public AspNetApplications AspNetApplications { get; set; }
}
下面是我添加AspNetUserRoles类型的新实体的代码,它在dbContext.SaveChanges()
IdentityUserRole
实现了一个与UserId
和RoleId
一致的复合外键。您的子类只为ApplicationId
设置了一个键,因此发生了以下两种情况之一:
ApplicationId
,在这种情况下,只能为任何给定的应用程序添加一个用户角色UserId
和RoleId
,因为它是相同的用户和角色,所以您违反了约束UserId
、RoleId
和ApplicationId
组成。由于您无法控制IdentityUserRole
的基本实现,因此确保这一点的最佳方法是使用fluent config。将以下内容添加到上下文类中
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<AspNetUserRoles>().HasKey(m => new { m.ApplicationId, m.UserId, m.RoleId });
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity().HasKey(m=>new{m.ApplicationId,m.UserId,m.RoleId});
}
另外,FWIW,您不需要为类命名
AspNet*
。如果您想要相同的表名,只需使用[table(“AspNetUserRoles”)]
来装饰类即可。我打算将ApplicationId添加为复合键,并且我尝试了您的方法,在该迁移中我可以将ApplicationId视为复合键,但它仍然抛出相同的错误。up脚本如下DropForeignKey(“dbo.AspNetUserRoles”、“ApplicationId”、“dbo.AspNetApplications”);AddForeignKey(“dbo.AspNetUserRoles”、“ApplicationId”、“dbo.AspNetApplications”、“ApplicationId”);您可能需要清空数据库并重新创建它。迁移似乎并没有从建模创建的中获取更改。您确实将该方法添加到了DbContext
子类中,对吗?我已经让它工作了,谢谢Chris。外键数据注释是问题所在。删除ForeignKey属性并将扩展模型类从AspNetUserRoles重命名为ApplicationUserRoles后,它工作正常。这里我还有一个问题。迁移创建了一个新表“ApplicationUserRoles”,其中UserId、RoleId和ApplicationId作为复合主键。您能告诉我如何使用这个新表进行角色身份验证,而不是AspNetUserRoles表吗?我的用户声明标识仍引用AspNetUserRoles。非常感谢
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<AspNetUserRoles>().HasKey(m => new { m.ApplicationId, m.UserId, m.RoleId });
}