Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 重复更新会导致跟踪错误_C#_Entity Framework Core - Fatal编程技术网

C# 重复更新会导致跟踪错误

C# 重复更新会导致跟踪错误,c#,entity-framework-core,C#,Entity Framework Core,Im将VisualStudio 2017与.Net Core 2和EntityFrameworkCore(v2.0.1)一起使用。该应用程序是一个控制台应用程序,它启动MQTT客户机,然后处理接收到的消息,并将它们存储到数据库中 每次应用程序启动时,以及在第一次更新时,它都会按预期工作。但是,每次使用相同数据进行后续更新时(无,一个或多个字段发生更改),它都会抛出System.InvalidOperationException,并显示以下消息: 无法跟踪实体类型“Entity1”的实例,因为 已

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

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

无法跟踪实体类型“Entity1”的实例,因为 已创建另一个键值为“[SomeKeyValue]”的实例 跟踪。附着现有实体时,请确保仅附着一个实体 将附加具有给定键值的实例

实体相当简单,仅使用一对多关系

我还有一个WebApi编写到同一个数据库时使用的相同存储库,在这里,相同的更新代码可以正常工作,不会出现错误。我连接了Console应用程序来使用WebApi,尽管它是完全相同的存储库和数据库,但这是可行的

我尝试了在互联网上找到的各种建议,例如显式分离实体,但都不起作用

此设置与Asp.NETWebAPI相同,使用依赖项注入

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

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

看来在IoC容器中配置DbContext需要在控制台应用程序中执行额外的步骤。而不是

services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString));
services.AddDbContext(options=>options.UseSqlServer(connectionString));
它需要一个附加参数来将ServiceLifetime指定为瞬态:

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

这似乎可以解决问题。

尝试在AddEntity中使用新上下文。您的DI在WebAPI中为每个请求实例化DbContext,您可能在console应用程序中重用DbContext实例。是的,这就是我最后所做的,但它违反了IoC原则。有没有办法在IoC容器中绑定它来创建一个新实例?我刚刚发现可以将DbContext配置为瞬态。这似乎可以停止错误,而不必在AddEntity中重新创建DbContext。
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();
}
services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString));
services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString), ServiceLifetime.Transient);