I have a problem, when will I do update in my database, I have this exception.
The instance of entity type 'ExpenseReport' 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 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values. tracked already
This is my method to do an update.
public async Task UpdateExpenseReportForm(Guid ExpenseReportId)
{
var totalValue = _uow.GetReadRepository<ExpenseItem>().FindByCondition(x => x.ExpenseReportId.Equals(ExpenseReportId)).Sum(x => x.Value);
var expenseReprot = await _uow.GetReadRepository<ExpenseReport>().FindByCondition(x => x.Id.Equals(ExpenseReportId)).FirstOrDefaultAsync().ConfigureAwait(false);
expenseReprot.TotalValue = totalValue - expenseReprot.AdvanceValue;
_uow.GetWriteRepository<ExpenseReport>().Update(expenseReprot);
await _uow.CommitAsync();
}
An important detail is that in this method _uow.GetReadRepository <ExpenseReport> ()
I'm already using AsNoTracking to not map it
These are methods that do get and update"repository dynamic"
public void Update(T entity)
{
_dbSet.Update(entity);
}
public IQueryable<T> FindByCondition(Expression<Func<T, bool>> expression)
{
return _dbSet.Where(expression).AsNoTracking();
}
You don't need to call
_dbSet.Update
because as the error message indicates the entity is already being tracked from your previous query.Try by removing the statement "AsNoTracking" from the
FindByCondition
method and simply call save in the "Update" method:Here is a nice generic implementation of the repository pattern that you may want to reuse:
Here is the interface:
Note that you only need to call "Attach" or "MarkModified" if the entity is not being tracked, in most scenarios you can simply make a query, modify some properties of a tracked entity and then call
SaveChanges
.You can also combine the repositories with a unit of work so you can have more control over transactions, etc... here is an example:
And the interface: