gpt4 book ai didi

c# - 为什么 EF Core 在自映射后将状态更改为已添加?

转载 作者:行者123 更新时间:2023-11-30 21:27:20 26 4
gpt4 key购买 nike

我在使用 EF Core (2.2.6) 和 AutoMapper (9.0.0) 进行实体映射时遇到了问题。

我的个人资料:

CreateMap<Product, Product>();

这是我的更新代码:

public async Task<RepositoryResult> UpdateAsync(Product product) {
var productFromDb = await _context.Products
.Include(p => p.PreparationMethods)
.Include(p => p.ProductAttributes)
.SingleOrDefaultAsync(p => p.Id == product.Id);

if (productFromDb == null) return RepositoryResult.NotFound(product.Id.ToString());
// product has state Detached here
_mapper.Map(product, productFromDb); // <== HERE
// product now has state Added
await _context.SaveChangesAsync();
return RepositoryResult.Success();
}

自映射后(await _context.SaveChangesAsync())我总是得到一个Exception

System.InvalidOperationException: 'The instance of entity type 'Product' cannot be tracked because another instance with the key value '{Id: 18}' is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached.'

经过一番调试,我发现:

  • product - 状态为Added
  • productFromDb - 状态为已修改

这就是我的问题所在。

为什么 AutoMapper(或 EF Core)认为应该添加 product?我该如何解决?

@Update 已解决

好的。我设法以某种方式解决了这个问题(?)。在我的 Controller 中,我有 GetById 方法,它有 AsNoTracking(),因为它应该返回 ReadOnly 值以避免意外更改。

该死的...这是一个非常糟糕的解决方案,因为我希望它在不跟踪的情况下返回一个对象,但我想这是不可能的。

public async Task<IActionResult> UpdateQuantity(int id, ProductQuantity quantity) {
var getResult = await _productRepository.GetByIdAsync(id);
if (getResult.Code == RepositoryStatusCodes.NotFound) return NotFound(getResult.Errors);
else if (!getResult.IsSuccess) return BadRequest(getResult.Errors);

var product = getResult.EntityResult;
product.Quantity = quantity.Quantity;

var updateResult = await _productRepository.UpdateAsync(product);
if (!updateResult.IsSuccess)
return BadRequest(updateResult.Errors);
else
return Ok();
}

我的获取方法:

public async Task<RepositoryResult<Product>> GetByIdAsync(int id) {
var product = await _context.Products
.Include(p => p.ProductAttributes)
.Include(p => p.PreparationMethods)
//.AsNoTracking() <--- comement on this sovled my problem
.SingleOrDefaultAsync(p => p.Id == id);

if (product == null)
return RepositoryResult<Product>.NotFound(id.ToString());
return RepositoryResult<Product>.Success(product);
}

最佳答案

尝试从上下文中分离产品,因为您检索到另一个具有相同 ID 的产品。尝试以下操作:

_mapper.Map(product, productFromDb); // <== HERE
_context.Entry(product).State = EntityState.Detached;
await _context.SaveChangesAsync();

关于c# - 为什么 EF Core 在自映射后将状态更改为已添加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57907857/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com