我将 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();
}
任何人都知道为什么会发生这种情况以及如何解决?
在 IoC 容器中配置 DbContext 似乎需要在控制台应用程序中执行额外的步骤。代替
services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString));
它需要一个附加参数来将 ServiceLifetime 指定为 Transient:
services.AddDbContext<MyContext>(options => options.UseSqlServer(connectionString), ServiceLifetime.Transient);
这似乎解决了这个问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句