将角色分配给扩展 Asp.Net 身份 2 错误中的用户违反主键约束 'PK_dbo.AspNetUserRoles'

Assigning a role to a user in extended Asp.Net Identity 2 error Violation of PRIMARY KEY constraint 'PK_dbo.AspNetUserRoles'

我已经为我的应用程序扩展了 AspNetUserRoles,我在 AspNetUserRoles table 中添加了一个新的 FK 列 ApplicationId。这背后的想法是允许同一用户在不同的应用程序中具有相同或不同的角色。 一切似乎都很好,直到我尝试将相同的角色添加到同一用户但是对于我开始收到错误的不同应用程序:

Violation of PRIMARY KEY constraint 'PK_dbo.AspNetUserRoles'. Cannot insert duplicate key in object '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);
    }

}

我的 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实现了UserIdRoleId一致的复合外键。您的 subclass 只为 ApplicationId 设置了一个键,因此发生了以下两种情况之一:

  1. 关键是 ApplicationId,在这种情况下,只能为任何给定的应用程序添加一个用户角色。
  2. 密钥是 UserIdRoleId,因为它是同一用户和同一角色,所以您违反了约束条件。

本质上需要保证组合键由UserIdRoleIdApplicationId组成。由于您无法控制 IdentityUserRole 的基本实现,确保这一点的最佳方法是使用流畅的配置。将以下内容添加到您的上下文 class.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<AspNetUserRoles>().HasKey(m => new { m.ApplicationId, m.UserId, m.RoleId });
}

另外,FWIW,您不需要命名您的 classes AspNet*。如果您想要相同的 table 名称,只需用 [Table("AspNetUserRoles")].

装饰 class