违反 Blazor 服务器端应用中的主键约束'PK_AspNetUsers'



我知道这个问题已经被问了很多次,但我看到的所有答案似乎都与所讨论的实体有关,这些实体来自与当前不同的上下文,例如ASP.NET MVC等客户端/服务器场景。

在我的情况下,这不是真的,因为所有的操作都发生在一个代码块中。如果有什么不同的话,这一切都在Blazor服务器端应用程序中。

我使用的是ASP.NET Identity,其Identity模型名为User。我有一个History模型(为了清晰起见,删除了不相关的属性(。。。

public class History {
public int Id { get; set; }
public string UserID { get; set; }
[ForeignKey(nameof(UserID))]
public virtual User User { get; set; }
}

我正在尝试创建一个新的History项目,如下所示。。。

string email = (await AuthenticationStateProvider.GetAuthenticationStateAsync())
.User.Identity.Name.ToLower();
User user = await Context.Users.SingleAsync(u => u.Email.ToLower() == email);
History h = new() {
// Other properties removed for clarity
UserID = user.Id,
};
Context.Histories.Add(h);
await Context.SaveChangesAsync();

但这是一个例外。。。

违反PRIMARY KEY约束"PK_AspNetUsers"。无法在对象"dbo.AspNetUsers"中插入重复的密钥。重复的密钥值为…

正如您所看到的,所有代码都发生在一个块中,因此从数据库中检索的User实体和我试图保存的新创建的History实体都应该在同一上下文中。我不明白它为什么要添加一个新的User

上下文以常规方式注入到Blazor组件中。。。

[Inject]
private ApplicationDbContext Context { get; set; }

并且在CCD_ 7中设置如下。。。

services.AddDbContext<ApplicationDbContext>(options => {
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
options.EnableSensitiveDataLogging();
options.EnableDetailedErrors();
}, ServiceLifetime.Transient);

这是一个相当成熟的应用程序,在其他地方做这种事情似乎都很好,只是这个新的History项目导致了异常,尽管我们在其他地方也做同样的事情。

我试过了。。。

  • 将用户的状态设置为未更改
  • 检索用户时添加AsNoTrackingWithIdentityResolution()
  • 设置User属性而不是UserId属性
  • 保存前将User属性设置为null

。。。但这些都无济于事。

作为一个实验,我尝试注入第二个上下文,并使用它来获取用户Id,然后将其处理并设置为null,以确保它不会一直存在。在这个阶段,原始上下文根本没有接触过用户,我有一个带有所需Id的普通字符串。然而,我仍然得到了相同的异常。

有什么想法吗?感谢

唉,原来我不仅叫错了树,而且在错误的森林里!

问题与History项本身的UserId属性无关,它是被省略的(看似无害的(其他属性之一(通过参数传入(,具有引用user的导航属性,这导致了异常。

我修改了代码,忽略了参数,直接从数据库中获取另一个属性,现在一切都很好。

不知道这是否会对任何人有所帮助,但我想我会把它作为一个答案发布,以防万一。

相关内容

  • 没有找到相关文章

最新更新