Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.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# 实体类型的实例';项目';无法跟踪,因为已在跟踪另一个具有{';Id';}相同键值的实例_C#_Entity Framework Core - Fatal编程技术网

C# 实体类型的实例';项目';无法跟踪,因为已在跟踪另一个具有{';Id';}相同键值的实例

C# 实体类型的实例';项目';无法跟踪,因为已在跟踪另一个具有{';Id';}相同键值的实例,c#,entity-framework-core,C#,Entity Framework Core,我知道已经有人问过这样的问题,但解决方案并没有帮助我 [Fact] public async Task UpdateAsync() { string newTitle = "newTitle1"; int newBrandId = 3; var item = await storeContext.Items.AsNoTracking().FirstOrDefaultAsync(); item.BrandId = newBrandId; item.Title

我知道已经有人问过这样的问题,但解决方案并没有帮助我

[Fact]
public async Task UpdateAsync()
{
    string newTitle = "newTitle1";
    int newBrandId = 3;
    var item = await storeContext.Items.AsNoTracking().FirstOrDefaultAsync();
    item.BrandId = newBrandId;
    item.Title = newTitle;
    storeContext.Entry(item).State = EntityState.Detached;
    await service.UpdateAsync(item); // exception inside
    var updatedItem = await storeContext.Items.AsNoTracking().FirstOrDefaultAsync();
    Assert.Equal(newTitle, updatedItem.Title);
    Assert.Equal(newBrandId, updatedItem.BrandId);
}

public async Task UpdateAsync(T entity)
{
    _dbContext.Entry(entity).State = EntityState.Modified; // exception when trying to change the state
    await _dbContext.SaveChangesAsync();
}
消息:System.InvalidOperationException:无法跟踪实体类型“Item”的实例,因为已在跟踪另一个具有{Id}相同键值的实例。附着现有实体时,请确保仅附着一个具有给定键值的实体实例。考虑使用“dBraveTopStudioBuffel.EnabelSythViDeAtCug”来查看冲突的键值。

有趣的是,即使没有从db检索到任何项,异常也是一样的,就像这样

//var item = await storeContext.Items.AsNoTracking().FirstOrDefaultAsync();
  var item = new Item()
  {
      Id = 1,
      BrandId = newBrandId,
      CategoryId = 1,
      MeasurementUnitId = 1,
      StoreId = 1,
      Title = newTitle
  };

我遇到的许多问题都有一个令人讨厌的根源。 简而言之:我已经很难理解为什么dbContext是作用域而不是单例的。这里是商店类型,但问题是相同的。 下面是简化的测试初始化代码

public TestBase()
{
    services = new ServiceCollection();
    storeContext = StoreContextMock.ConfigureStoreContext(services, output);
    serviceProvider = services.BuildServiceProvider();
}
public static StoreContext ConfigureStoreContext(IServiceCollection services)
{
    services.AddDbContext<StoreContext>(c =>
        c.UseInMemoryDatabase(Guid.NewGuid().ToString()).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking));

    var serviceProvider = services.BuildServiceProvider();
    var storeContext = serviceProvider.GetRequiredService<StoreContext>();
    storeContext .Stores.Add(new Store { Title = "John's store", Address = "NY", Description = "Electronics best deals", SellerId = "john@mail.com" });
    storeContext .Stores.Add(new Store { Title = "Jennifer's store", Address = "Sydney", Description = "Fashion", SellerId = "jennifer@mail.com" });
    storeContext .SaveChanges();
    return storeContext ;
}
这是dbContext应该受到范围限制的众多原因之一。
感谢。

我在按实体框架复制数据库中的一些记录并更改另一列的实体键时遇到了相同的问题。 跟踪模式更改未解决此问题

通过在EntityTypeConfiguration中正确设置主键,以包含此处描述为x.EntityTwoKey的更改值,该问题已得到修复

builder.HasKey(x => new { x.EntityOneKey, x.EntityTwoKey });

EF core 2.2也有同样的问题。我从未在其他应用程序中体验过这一点

以某种方式重写了我所有的更新函数:

public bool Update(Entity entity)
{
    try
    {   
       var entry = _context.Entries.First(e=>e.Id == entity.Id);
       _context.Entry(entry).CurrentValues.SetValues(entity);
       _context.SaveChanges();
       return true;
    }
    catch (Exception e)
    {
         // handle correct exception
         // log error
         return false;
    }
}

Alexandar的答案是完全禁用跟踪,解决了我的问题,但我很担心,因为我不知道这会对我的应用程序的其余部分造成什么影响。因此,我转到Microsoft文档,发现:

如果要操作实体实例并使用SaveChanges()将这些更改持久化到数据库中,则应而不是禁用更改跟踪

此方法为使用这些选项创建的所有上下文设置默认行为,但您可以使用QueryTrackingBehavior为上下文实例覆盖此行为,也可以使用AsNoTracking(IQueryable)和AsTracking(IQueryable)方法覆盖单个查询

因此,我的解决方案是仅在需要时禁用跟踪。因此,我在代码的另一部分中使用了这个选项,从数据库中检索到了相同的条目,从而解决了我的问题:

var条目=等待上下文
.一些桌子
.AsNoTracking()//这就是您要找的
.查找(id);

在我的例子中,我在两条IFs语句中运行SaveChanges两次时遇到了这个错误。我将SaveChanges移到这两个代码块之外。只是我的服务层中的一个旁注,它使用AsNoTracking()查询数据


我在尝试更新值时遇到了同样的问题。然后我发现了我用这个的问题

services.AddDbContext<StudentContext>(option => option.UseSqlServer(Configuration.GetConnectionString("databasename")),ServiceLifetime.Singleton);
services.AddDbContext(option=>option.UseSqlServer(Configuration.GetConnectionString(“databasename”)),ServiceLifetime.Singleton);
然后我取消了终身制,它对我很有效

services.AddDbContext<StudentContext>(option => option.UseSqlServer(Configuration.GetConnectionString("databasename")));
services.AddDbContext(option=>option.UseSqlServer(Configuration.GetConnectionString(“databasename”));

对我来说,这就是解决方案:

public void Update(int id, T obj)
        {
            var entry = table.Find(id);
            _context.Entry(entry).CurrentValues.SetValues(obj);
        }

基于布莱恩给出的解决方案。我想我使用了更新版本的EF/自动映射。这对我很有用。

在我的例子中,在我将主键列
Id
设置为标识列后,上述问题得到解决。

尝试删除此
storeContext.Entry(item).State=EntityState.Distached
然后像问题结束时那样手动创建项确保单元测试中使用的
DbContext
与服务中使用的
storeContext
是同一个实例。确保没有其他线程可以保存该实例object@tomassino同样,一切都没有改变。即使只有一个测试运行,错误也会保留,因此我怀疑线程。@CodeNotFound它是相同的,只包装在存储库中。如何在设置“跟踪”为“关闭”时自动更新一对多关系中的子项?仅供参考,Microsoft文档:“如果要操作实体实例并使用SaveChanges()将这些更改持久化到数据库中,则不应禁用更改跟踪。“你是我的英雄,这对我有用,而其他一切都没有。这里也是EF核心2.2。谢谢你,伙计!!仅供参考,我的所有DBContext条目都有作用域,而不是单例。就连微软也建议去调查,但在我的情况下,已经这样做了。效果很好!杰出的谢谢。这是这篇非常全面的文章中描述的选项之一:
services.AddDbContext<StudentContext>(option => option.UseSqlServer(Configuration.GetConnectionString("databasename")));
public void Update(int id, T obj)
        {
            var entry = table.Find(id);
            _context.Entry(entry).CurrentValues.SetValues(obj);
        }