重复更新导致跟踪错误 [英] Repeated Update causes tracking error

查看:41
本文介绍了重复更新导致跟踪错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Visual Studio 2017和.Net Core 2和EntityFrameworkCore(v2.0.1).该应用程序是一个控制台应用程序,它启动MQTT客户端,然后处理收到的消息,并将它们存储到数据库中.

Im using VisualStudio 2017 with .Net Core 2 and EntityFrameworkCore (v2.0.1). The application is a console application which starts an MQTT Client and then processes the received messages, storing them into a database.

每次启动应用程序时,在第一次更新时,它将按预期运行.但是,在以后的每次更新中,使用相同的数据(没有更改,更改一个或多个字段)时,它将引发System.InvalidOperationException并显示以下消息:

Each time the application starts and on the first update it works as expected. However on each subsequent update with the same data (none, one or more fields are changed), it throws an System.InvalidOperationException with the following message:

无法跟踪实体类型"Entity1"的实例,因为另一个具有键值"[SomeKeyValue]"的实例已在跟踪.附加现有实体时,请确保只有一个实体具有给定键值的实例被附加.

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.

实体非常简单,仅使用一对多关系.

The entities are fairly simple, only using a One-To-Many relationship.

我还拥有WebApi写入相同数据库所使用的相同存储库,并且此处相同的更新代码按预期工作,没有错误.我连接了控制台应用程序以改为使用WebApi,即使它与存储库和数据库完全相同,它也可以正常工作.

I also have the same repository used in a WebApi writing to the same database, and here the same update code works as expected without errors. I hooked up the Console App to use the WebApi instead, and this works, even though it is exactly the same Repository and Database.

我尝试了在互联网上找到的各种建议,例如,明确分离实体,但没有一个起作用.

I tried various recommendations I found on the internet, which is for example to explicitly detach the entity, but none of that worked.

使用依赖项注入的设置与Asp.Net WebApi的设置相同

The setup is the same as for the Asp.Net WebApi, using dependency injection

services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString));

一对多关系的配置如下:

The One-To-Many Relations is configured like this:

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; }
  ...
}

用于添加实体的存储库代码:

The repository code for adding entity:

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();
}

有人知道为什么会发生这种情况以及如何解决?

Anybody any idea why this is happening and how it can be fixed?

推荐答案

看来,在IoC容器中配置DbContext需要在控制台应用程序内部执行额外的步骤.代替

It appears that configuring DbContext in the IoC container requires an extra step inside of a Console Application. Instead of

services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString));

它需要一个附加参数来将ServiceLifetime指定为Transient:

it requires an addition parameter to specify the ServiceLifetime as Transient:

services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString), ServiceLifetime.Transient);

这似乎可以解决问题.

这篇关于重复更新导致跟踪错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆