我将 VisualStudio 2017 与 .Net Core 2 和 EntityFrameworkCore (v2.0.1) 结合使用。该应用程序是一个控制台应用程序,它启动 MQTT 客户端,然后处理接收到的消息,并将其存储到数据库中。
每次应用程序启动和第一次更新时,它都会按预期工作。然而,在每次使用相同数据进行后续更新时(没有更改、一个或多个字段发生更改),它会抛出 System.InvalidOperationException 并显示以下消息:
The instance of entity type 'Entity1' cannot be tracked because another instance with the key value '[SomeKeyValue]' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.
实体相当简单,仅使用一对多关系。
我还拥有在写入同一数据库的 WebApi 中使用的相同存储库,并且这里相同的更新代码按预期工作,没有错误。我连接了控制台应用程序以使用 WebApi,并且这有效,即使它是完全相同的存储库和数据库。
我尝试了在互联网上找到的各种建议,例如显式分离实体,但没有一个起作用。
设置与 Asp.Net WebApi 相同,使用依赖注入(inject)
services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString));
一对多关系的配置如下:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Entity1>()
.HasOne<Entity2>(di => di.Entity1)
.WithMany(d => d.Entity2)
.HasForeignKey(d => d.Entity1Id);
}
实体是:
public class Entity1: ClientChangeTracker
{
[Key]
public string Id{ get; set; }
public ICollection<Entity2> Entity2{ get; set; }
...
}
public class Entity2: ClientChangeTracker
{
[Key]
public string Id{ get; set; }
public Entity1 Entity1{get; set; }
public string Entity1Id{ get; set; }
...
}
添加实体的存储库代码:
public void AddEntity(Entity1 entity1)
{
if (_context.Entity1s.Any(x => x.Id== entity1.Id))
{
_context.Entity1s.Update(entity1).Entity;
}
else
{
_context.Entity1s.Add(entity1).Entity;
}
_context.SaveChanges();
}
有人知道为什么会发生这种情况以及如何解决它吗?
最佳答案
看来,在 IoC 容器中配置 DbContext 需要在控制台应用程序内部执行额外的步骤。而不是
services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString));
它需要一个附加参数来将 ServiceLifetime 指定为 Transient:
services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString), ServiceLifetime.Transient);
这似乎可以解决问题。
关于c# - 重复更新导致跟踪错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48950274/