重复更新会导致跟踪错误

时间:2018-02-23 14:38:48

标签: c# entity-framework-core

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

每次应用程序启动时,第一次更新都会按预期工作。但是,在每次使用相同数据的后续更新(无,一个或多个字段已更改)时,它会抛出System.InvalidOperationException,并显示以下消息:

  

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

实体非常简单,只使用一对多关系。

我也在WebApi中使用相同的存储库写入同一个数据库,这里相同的更新代码按预期工作而没有错误。我将控制台应用程序连接起来使用WebApi,这样就行了,即使它与存储库和数据库完全相同。

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

使用依赖注入

,设置与Asp.Net WebApi的设置相同
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();
}

任何人都知道为什么会发生这种情况以及如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

似乎在IoC容器中配置DbContext需要在控制台应用程序内部执行额外步骤。而不是

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

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

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

这似乎解决了这个问题。