我已经为我的应用程序扩展了AspNetUserRoles,我在AspNetUserRoles
表中添加了一个新的FK列ApplicationId
。其背后的思想是允许相同的用户以相同或不同的角色出现在不同的应用程序中。一切似乎都很好,直到我试图将相同的角色添加到相同的用户,但对于不同的应用程序,我已经开始得到错误:
谁能帮我解决这个问题?违反了PRIMARY KEY约束'PK_dbo.AspNetUserRoles'。不能在对象'dbo.AspNetUserRoles'中插入重复键。
我的identiymodels如下
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);
}
}
我的AspNetApplications和AspNetUserRoles模型如下
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()
抛出错误
var aspNetUserRole = new AspNetUserRoles
{
UserId = userId,
RoleId = roleId,
ApplicationId = applicationId,
};
dbContext.AspNetUserRoles.Add(aspNetUserRole);
dbContext.SaveChanges();
IdentityUserRole
实现了与UserId
和RoleId
一致的复合外键。您的子类只有ApplicationId
的键集,因此会发生两件事之一:
- 密钥是
ApplicationId
,在这种情况下,只能为任何给定的应用程序添加一个用户角色。 - 键是
UserId
和RoleId
,因为它是相同的用户和相同的角色,你违反了约束。
UserId
、RoleId
、和 ApplicationId
组成。由于您无法控制IdentityUserRole
的基本实现,因此确保这一点的最佳方法是使用fluent配置。将以下内容添加到您的上下文类中。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<AspNetUserRoles>().HasKey(m => new { m.ApplicationId, m.UserId, m.RoleId });
}
另外,顺便说一句,你不需要把你的类命名为AspNet*
。如果您想要相同的表名,只需用[Table("AspNetUserRoles")]
修饰类。