system.invalidoperationException:无法跟踪实体类型的实例,因为{' id'}的另一个具有相同密钥值的实例已经存在
我在Azure上部署了一个API,其中我有一个crcart
实体。我想确保,如果已经有一个与用户关联的购物车和具有“保存”状态的客户,那么您将无法使用该状态添加更多。
这里的问题是,我在crcart
服务上对我的帖子方法进行了验证,并且可以正常工作,但是在我的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;
}
我已经掌握了服务范围,因此这不是问题。请提供帮助,因为我不知道这是什么原因引起的,我有一个截止日期。谢谢。
edit
我的baseerpository
我有通用方法
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();
}
edgrang> edit> edit 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();
}
I have an Api deployed on Azure in which I have a CrCart
entity. I want to make sure that if there is already a cart associated with a user and a customer with the status "Saved" you can't add more with that status.
The issue here is that I make that validation on my Post method on my CrCart
Service and it works fine but on my Put method it doesn't.
Here is the error:
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...
Here is the code for both my Insert
and Update
methods:
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;
}
I already have my service Scopped so that's not the issue. Please help because I don't know what it is causing this and I have a deadline for this project. Thanks.
EDIT
My BaseRepository
in which I have generic methods
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();
}
}
And my UnitOfWork
where I have all the repositories
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();
}
EDIT 2
Here's the working code which I don't know if it is done properly
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有时,如果您使用
async
使用没有的实体等待
等待的实体,以及您的第一个async
任务完成之前,您开始调用另一个任务,将投掷此异常
。因此,此外,您应该使用实体使用
asnotracking()
方法,您将不会更改,然后无法保存(只需读取)。更新1:
在您的代码末尾,请检查以下行:
也许您需要在
_unitofwork.crcartrepository.update(cart);
更新2:
之前添加
等待
。或者,如果您有最新的EF Core,则可以用asnotrackingWithIdentityResolution()
替换它。更新3
也可以尝试以下操作:
Sometimes if you use
async
methods with entities withoutawait
or waiting, and before your firstasync
task finished, you started to call another task, it will throw thisexception
.So, in addition, you should use
AsNoTracking()
method with entities you will not change and then will not save (just read).UPDATE 1:
In the end of your code check this lines:
Maybe you need to add
await
before_unitOfWork.CrCartRepository.Update(cart);
UPDATE 2:
or you can replace it with
AsNoTrackingWithIdentityResolution()
if you have newest EF CORE.UPDATE 3
Also try this: