实体类型的实例'产品'无法跟踪,因为已经跟踪了具有相同键值的另一个实例

时间:2018-04-12 13:58:54

标签: c# entity-framework aspnetboilerplate change-tracking asp.net-boilerplate

我使用下面的代码进行了测试,以更新Product

var existing = await _productRepository.FirstOrDefaultAsync(c => c.Id == input.Id);
if (existing == null)
    throw new UserFriendlyException(L("ProductNotExist"));
var updatedEntity = ObjectMapper.Map<Product>(input);
var entity = await _productRepository.UpdateAsync(updatedEntity);

但它引发了一个例外:

  

Mvc.ExceptionHandling.AbpExceptionFilter - 实体类型的实例&#39;产品&#39;无法跟踪,因为已经跟踪了具有{&#39; Id&#39;}的相同键值的另一个实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。

这是由查询existing引起的。对此有什么解决方案吗?

4 个答案:

答案 0 :(得分:3)

由于您未使用existing实体,请不要加载它。

使用AnyAsync检查它是否存在:

var exists = await _productRepository.GetAll().AnyAsync(c => c.Id == input.Id); // Change
if (!exists)                                                                    // this
    throw new UserFriendlyException(L("ProductNotExist"));

var updatedEntity = ObjectMapper.Map<Product>(input);
var entity = await _productRepository.UpdateAsync(updatedEntity);

如果您要映射到existing实体:

var existing = await _productRepository.FirstOrDefaultAsync(c => c.Id == input.Id);
if (existing == null)
    throw new UserFriendlyException(L("ProductNotExist"));

var updatedEntity = ObjectMapper.Map(input, existing); // Change this

答案 1 :(得分:2)

AsNoTracking()可以帮到你。

答案 2 :(得分:0)

检查updatedEntity.Id的值,如果它为零则使用以下代码。

var updatedEntity = ObjectMapper.Map<Product>(input);
updatedEntity.Id = input.Id; //set Id manually
var entity = await _productRepository.UpdateAsync(updatedEntity);

答案 3 :(得分:-1)

添加用于分离的代码

_dbcontext.Entry(oldEntity).State = EntityState.Detached;