System.InvalidOperationException: 无法跟踪实体类型的实例,因为已存在具有与 {'Id'} 相同键值的另一个实例
System.InvalidOperationException: The instance of entity type cannot be tracked because another instance with the same key value for {'Id'} is already
我在 Azure 上部署了一个 Api,其中有一个 CrCart
实体。我想确保如果已经有一个与状态为“已保存”的用户和客户相关联的购物车,您将无法添加更多具有该状态的内容。
这里的问题是我在我的 CrCart
服务上对我的 Post 方法进行了验证并且它工作正常但在我的 Put 方法上它没有。
这里是错误:
System.InvalidOperationException: The instance of entity type 'CrCart' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using...
这是我的 Insert
和 Update
方法的代码:
public async Task Insert(CrCart cart)
{
var user = await _unitOfWork.CrUserRepository.GetById(cart.IdUser);
var customer = await _unitOfWork.CrCustomerRepository.GetById(cart.IdCustomer);
var carts = _unitOfWork.CrCartRepository.GetAll();
carts = carts.Where(x => x.IdCustomer == cart.IdCustomer && x.Status == "Saved" && x.IdUser == cart.IdUser);
if (user == null)
{
throw new BusinessException("El usuario introducido no existe");
}
if (customer == null)
{
throw new BusinessException("El cliente introducido no existe");
}
if (carts.Count() >= 1 && cart.Status == "Saved") {
throw new BusinessException("Ya existe un carrito con estado -Saved- asignado al cliente " +
customer.Name);
}
await _unitOfWork.CrCartRepository.Insert(cart);
await _unitOfWork.SaveChangesAsync();
}
public async Task<bool> Update(CrCart cart)
{
var user = await _unitOfWork.CrUserRepository.GetById(cart.IdUser);
var customer = await _unitOfWork.CrCustomerRepository.GetById(cart.IdCustomer);
var carts = _unitOfWork.CrCartRepository.GetAll();
carts = carts.Where(x => x.IdCustomer == cart.IdCustomer && x.Status == "Saved" && x.IdUser == cart.IdUser);
if (user == null)
{
throw new BusinessException("El usuario introducido no existe");
}
if (customer == null)
{
throw new BusinessException("El cliente introducido no existe");
}
if (carts.Count() >= 1 && cart.Status == "Saved")
{
throw new BusinessException("Ya existe un carrito con estado -Saved- asignado al cliente " +
customer.Name);
}
_unitOfWork.CrCartRepository.Update(cart);
await _unitOfWork.SaveChangesAsync();
return true;
}
我的服务已经 Scopped,所以这不是问题所在。请帮忙,因为我不知道是什么原因造成的,而且我有这个项目的最后期限。谢谢。
编辑
我的 BaseRepository
我有通用方法
public class BaseRepository<T> : IBaseRepository<T> where T: BaseEntity
{
private readonly db_crijoyaContext _context;
protected readonly DbSet<T> _entities;
public BaseRepository(db_crijoyaContext context)
{
_context = context;
_entities = context.Set<T>();
}
public IEnumerable<T> GetAll()
{
return _entities.AsEnumerable();
}
public async Task<T> GetById(int id)
{
return await _entities.FindAsync(id);
}
public async Task Insert(T entity)
{
await _entities.AddAsync(entity);
//await _context.SaveChangesAsync();
}
public void Update(T entity)
{
_entities.Update(entity);
//await _context.SaveChangesAsync();
}
public async Task Delete(int id)
{
T entity = await GetById(id);
_entities.Remove(entity);
//await _context.SaveChangesAsync();
}
}
还有我的 UnitOfWork
我拥有所有存储库
public class UnitOfWork : IUnitOfWork
{
private readonly db_crijoyaContext _context;
private readonly ICrProductRepository _productRepsitory;
private readonly IBaseRepository<CrCompany> _companyRepository;
private readonly IBaseRepository<CrCategory> _categoryRepository;
private readonly IBaseRepository<CrCart> _cartRepository;
private readonly IBaseRepository<CrCustomer> _customerRepository;
private readonly IBaseRepository<CrUser> _userRepository;
private readonly IBaseRepository<CrOrder> _orderRepository;
private readonly IBaseRepository<CrCity> _cityRepository;
private readonly ICrUserInfoRepository _userInfoRepository;
private readonly ICrCountryRepository _countryRepository;
public UnitOfWork(db_crijoyaContext context)
{
_context = context;
}
public ICrProductRepository CrProductRepository => _productRepsitory ?? new CrProductRepository(_context);
public IBaseRepository<CrCategory> CrCategoryRepository => _categoryRepository ?? new BaseRepository<CrCategory>(_context);
public IBaseRepository<CrCompany> CrCompanyRepository => _companyRepository ?? new BaseRepository<CrCompany>(_context);
public IBaseRepository<CrUser> CrUserRepository => _userRepository ?? new BaseRepository<CrUser>(_context);
public IBaseRepository<CrCart> CrCartRepository => _cartRepository ?? new BaseRepository<CrCart>(_context);
public IBaseRepository<CrCustomer> CrCustomerRepository => _customerRepository ?? new BaseRepository<CrCustomer>(_context);
public IBaseRepository<CrOrder> CrOrderRepository => _orderRepository ?? new BaseRepository<CrOrder>(_context);
public IBaseRepository<CrCity> CrCityRepository => _cityRepository ?? new BaseRepository<CrCity>(_context);
public ICrUserInfoRepository CrUserInfoRepository => _userInfoRepository ?? new CrUserInfoRepository(_context);
public ICrCountryRepository CrCountryRepository => _countryRepository ?? new CrCountryRepository(_context);
public void Dispose()
{
if(_context != null)
{
_context.Dispose();
}
}
public void SaveChanges()
{
_context.SaveChanges();
}
public async Task SaveChangesAsync()
{
await _context.SaveChangesAsync();
}
编辑 2
这是工作代码,我不知道它是否正确完成
public async Task<bool> Update(CrCart cart)
{
var user = await _unitOfWork.CrUserRepository.GetById(cart.IdUser);
var customer = await _unitOfWork.CrCustomerRepository.GetById(cart.IdCustomer);
var carts = _unitOfWork.CrCartRepository.GetAllWithNoTracking();
carts = carts.Where(x => x.IdCustomer == cart.IdCustomer && x.Status == "Saved" && x.IdUser == cart.IdUser);
if (user == null)
{
throw new BusinessException("El usuario introducido no existe");
}
if (customer == null)
{
throw new BusinessException("El cliente introducido no existe");
}
if (carts.Count() >= 1 && cart.Status == "Saved")
{
throw new BusinessException("Ya existe un carrito con estado -Saved- asignado al cliente " +
customer.Name);
}
_unitOfWork.CrCartRepository.Update(cart);
await _unitOfWork.SaveChangesAsync();
return true;
}
public IEnumerable<T> GetAllWithNoTracking()
{
return _entities.AsNoTracking().AsEnumerable();
}
有时,如果您在没有 await
或等待的情况下对实体使用 async
方法,并且在您的第一个 async
任务完成之前,您开始调用另一个任务,它将抛出此 exception
.
因此,此外,您应该对不会更改的实体使用 AsNoTracking()
方法,也不会保存(只读)。
更新 1:
在您的代码末尾检查以下行:
_unitOfWork.CrCartRepository.Update(cart);
await _unitOfWork.SaveChangesAsync();
也许你需要在_unitOfWork.CrCartRepository.Update(cart);
之前加上await
更新 2:
public IEnumerable<T> GetAllWithNoTracking()
{
return _entities.AsNoTracking().AsEnumerable();
}
public async Task<T?> GetByIdWithNoTracking(int id)
{
return await _entities.AsNoTracking().FirstOrDefault(x => x.id == id);
}
或者如果您有最新的 EF CORE,您可以将其替换为 AsNoTrackingWithIdentityResolution()
。
更新 3
也试试这个:
_context.Entry(entity).State = EntityState.Modified;
_context.SaveChanges();
我在 Azure 上部署了一个 Api,其中有一个 CrCart
实体。我想确保如果已经有一个与状态为“已保存”的用户和客户相关联的购物车,您将无法添加更多具有该状态的内容。
这里的问题是我在我的 CrCart
服务上对我的 Post 方法进行了验证并且它工作正常但在我的 Put 方法上它没有。
这里是错误:
System.InvalidOperationException: The instance of entity type 'CrCart' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using...
这是我的 Insert
和 Update
方法的代码:
public async Task Insert(CrCart cart)
{
var user = await _unitOfWork.CrUserRepository.GetById(cart.IdUser);
var customer = await _unitOfWork.CrCustomerRepository.GetById(cart.IdCustomer);
var carts = _unitOfWork.CrCartRepository.GetAll();
carts = carts.Where(x => x.IdCustomer == cart.IdCustomer && x.Status == "Saved" && x.IdUser == cart.IdUser);
if (user == null)
{
throw new BusinessException("El usuario introducido no existe");
}
if (customer == null)
{
throw new BusinessException("El cliente introducido no existe");
}
if (carts.Count() >= 1 && cart.Status == "Saved") {
throw new BusinessException("Ya existe un carrito con estado -Saved- asignado al cliente " +
customer.Name);
}
await _unitOfWork.CrCartRepository.Insert(cart);
await _unitOfWork.SaveChangesAsync();
}
public async Task<bool> Update(CrCart cart)
{
var user = await _unitOfWork.CrUserRepository.GetById(cart.IdUser);
var customer = await _unitOfWork.CrCustomerRepository.GetById(cart.IdCustomer);
var carts = _unitOfWork.CrCartRepository.GetAll();
carts = carts.Where(x => x.IdCustomer == cart.IdCustomer && x.Status == "Saved" && x.IdUser == cart.IdUser);
if (user == null)
{
throw new BusinessException("El usuario introducido no existe");
}
if (customer == null)
{
throw new BusinessException("El cliente introducido no existe");
}
if (carts.Count() >= 1 && cart.Status == "Saved")
{
throw new BusinessException("Ya existe un carrito con estado -Saved- asignado al cliente " +
customer.Name);
}
_unitOfWork.CrCartRepository.Update(cart);
await _unitOfWork.SaveChangesAsync();
return true;
}
我的服务已经 Scopped,所以这不是问题所在。请帮忙,因为我不知道是什么原因造成的,而且我有这个项目的最后期限。谢谢。
编辑
我的 BaseRepository
我有通用方法
public class BaseRepository<T> : IBaseRepository<T> where T: BaseEntity
{
private readonly db_crijoyaContext _context;
protected readonly DbSet<T> _entities;
public BaseRepository(db_crijoyaContext context)
{
_context = context;
_entities = context.Set<T>();
}
public IEnumerable<T> GetAll()
{
return _entities.AsEnumerable();
}
public async Task<T> GetById(int id)
{
return await _entities.FindAsync(id);
}
public async Task Insert(T entity)
{
await _entities.AddAsync(entity);
//await _context.SaveChangesAsync();
}
public void Update(T entity)
{
_entities.Update(entity);
//await _context.SaveChangesAsync();
}
public async Task Delete(int id)
{
T entity = await GetById(id);
_entities.Remove(entity);
//await _context.SaveChangesAsync();
}
}
还有我的 UnitOfWork
我拥有所有存储库
public class UnitOfWork : IUnitOfWork
{
private readonly db_crijoyaContext _context;
private readonly ICrProductRepository _productRepsitory;
private readonly IBaseRepository<CrCompany> _companyRepository;
private readonly IBaseRepository<CrCategory> _categoryRepository;
private readonly IBaseRepository<CrCart> _cartRepository;
private readonly IBaseRepository<CrCustomer> _customerRepository;
private readonly IBaseRepository<CrUser> _userRepository;
private readonly IBaseRepository<CrOrder> _orderRepository;
private readonly IBaseRepository<CrCity> _cityRepository;
private readonly ICrUserInfoRepository _userInfoRepository;
private readonly ICrCountryRepository _countryRepository;
public UnitOfWork(db_crijoyaContext context)
{
_context = context;
}
public ICrProductRepository CrProductRepository => _productRepsitory ?? new CrProductRepository(_context);
public IBaseRepository<CrCategory> CrCategoryRepository => _categoryRepository ?? new BaseRepository<CrCategory>(_context);
public IBaseRepository<CrCompany> CrCompanyRepository => _companyRepository ?? new BaseRepository<CrCompany>(_context);
public IBaseRepository<CrUser> CrUserRepository => _userRepository ?? new BaseRepository<CrUser>(_context);
public IBaseRepository<CrCart> CrCartRepository => _cartRepository ?? new BaseRepository<CrCart>(_context);
public IBaseRepository<CrCustomer> CrCustomerRepository => _customerRepository ?? new BaseRepository<CrCustomer>(_context);
public IBaseRepository<CrOrder> CrOrderRepository => _orderRepository ?? new BaseRepository<CrOrder>(_context);
public IBaseRepository<CrCity> CrCityRepository => _cityRepository ?? new BaseRepository<CrCity>(_context);
public ICrUserInfoRepository CrUserInfoRepository => _userInfoRepository ?? new CrUserInfoRepository(_context);
public ICrCountryRepository CrCountryRepository => _countryRepository ?? new CrCountryRepository(_context);
public void Dispose()
{
if(_context != null)
{
_context.Dispose();
}
}
public void SaveChanges()
{
_context.SaveChanges();
}
public async Task SaveChangesAsync()
{
await _context.SaveChangesAsync();
}
编辑 2
这是工作代码,我不知道它是否正确完成
public async Task<bool> Update(CrCart cart)
{
var user = await _unitOfWork.CrUserRepository.GetById(cart.IdUser);
var customer = await _unitOfWork.CrCustomerRepository.GetById(cart.IdCustomer);
var carts = _unitOfWork.CrCartRepository.GetAllWithNoTracking();
carts = carts.Where(x => x.IdCustomer == cart.IdCustomer && x.Status == "Saved" && x.IdUser == cart.IdUser);
if (user == null)
{
throw new BusinessException("El usuario introducido no existe");
}
if (customer == null)
{
throw new BusinessException("El cliente introducido no existe");
}
if (carts.Count() >= 1 && cart.Status == "Saved")
{
throw new BusinessException("Ya existe un carrito con estado -Saved- asignado al cliente " +
customer.Name);
}
_unitOfWork.CrCartRepository.Update(cart);
await _unitOfWork.SaveChangesAsync();
return true;
}
public IEnumerable<T> GetAllWithNoTracking()
{
return _entities.AsNoTracking().AsEnumerable();
}
有时,如果您在没有 await
或等待的情况下对实体使用 async
方法,并且在您的第一个 async
任务完成之前,您开始调用另一个任务,它将抛出此 exception
.
因此,此外,您应该对不会更改的实体使用 AsNoTracking()
方法,也不会保存(只读)。
更新 1: 在您的代码末尾检查以下行:
_unitOfWork.CrCartRepository.Update(cart);
await _unitOfWork.SaveChangesAsync();
也许你需要在_unitOfWork.CrCartRepository.Update(cart);
await
更新 2:
public IEnumerable<T> GetAllWithNoTracking()
{
return _entities.AsNoTracking().AsEnumerable();
}
public async Task<T?> GetByIdWithNoTracking(int id)
{
return await _entities.AsNoTracking().FirstOrDefault(x => x.id == id);
}
或者如果您有最新的 EF CORE,您可以将其替换为 AsNoTrackingWithIdentityResolution()
。
更新 3 也试试这个:
_context.Entry(entity).State = EntityState.Modified;
_context.SaveChanges();