【问题标题】:Assigning a role to a user in extended Asp.Net Identity 2 error Violation of PRIMARY KEY constraint 'PK_dbo.AspNetUserRoles'在扩展的 Asp.Net Identity 2 错误中将角色分配给用户违反 PRIMARY KEY 约束“PK_dbo.AspNetUserRoles”
【发布时间】:2015-12-07 21:50:52
【问题描述】:

我为我的应用程序扩展了 AspNetUserRoles,我在 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);
    }

}

我的 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();

【问题讨论】:

    标签: asp.net-mvc asp.net-identity asp.net-identity-2 user-roles


    【解决方案1】:

    IdentityUserRole 实现了一个与UserIdRoleId 一致的复合外键。您的子类只有 ApplicationId 的密钥集,因此发生了以下两种情况之一:

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

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

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<AspNetUserRoles>().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");
    • 您可能需要炸毁您的数据库并重新创建它。迁移似乎没有从OnModelCreating 中获得变化。您确实将该方法添加到您的 DbContext 子类中,对吗?
    • 我已经成功了,谢谢克里斯。外键数据注释是问题所在。删除 ForeignKey 属性并将我的扩展模型类从 AspNetUserRoles 重命名为 ApplicationUserRoles 后,它工作正常。这里我还有一个问题。迁移创建了一个新表“ApplicationUserRoles”,其中 UserId、RoleId 和 ApplicationId 作为复合主键。你能告诉我如何利用这个新表而不是 AspNetUserRoles 表进行角色身份验证吗?我的用户声明身份仍然引用 AspNetUserRoles。非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-17
    • 1970-01-01
    • 1970-01-01
    • 2022-01-17
    相关资源
    最近更新 更多