【发布时间】:2021-06-11 19:56:27
【问题描述】:
我正在使用 Blazor Server 中的 EF Core 处理表单。我在实体跟踪方面遇到了许多问题,因此我将所有查询都设置为 AsNoTracking,并设计了我的服务来为每个查询创建一个新的 dbcontext 实例。我认为这是合适的,因为不会编辑任何返回值 - 只会存储用户输入的表单数据和对查询字段的 id 引用,例如员工编号。对于插入数据,我使用this:
using var context = Factory.CreateDbContext();
context.SetupForm.Attach(model);
context.Entry(model).State = EntityState.Added;
await context.SaveChangesAsync();
我附加数据而不是添加数据,然后将表单对象状态设置为已添加。这可确保 EF Core 在插入表单数据时不会尝试插入现有员工对象。
问题始于表单的一部分,该部分可以包含用户想要的任意数量的项目。选择几个员工并输入相关数据。当他们提交表单时,他们可能在多个项目中选择了同一个员工。由于这些员工是从不同的上下文中选择的,因此它们是具有相同 ID 的两个独立实例。当然,EF Core 不喜欢这样,会抛出这样的错误:
The instance of entity type 'Principal' cannot be tracked because another instance with the key value '{EmployeeID: 1234}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
我了解为什么会发生此错误,但我需要能够以这种方式附加多个实体。我该如何解决这个问题?
我可以做的一件事是手动分配外键,但这会很严格,并且需要在模型更改时进行更新。
【问题讨论】:
标签: c# entity-framework-core blazor change-tracking