I have this class that I use for DB operations:
public class EntityService<TEntity> : IRepository<TEntity> where TEntity : BaseModel
{
ApplicationDbContext _context;
private DbSet<TEntity> _entities;
public EntityService()
{
_context = new ApplicationDbContext();
}
public virtual void Update(TEntity entity)
{
if (entity == null)
throw new ArgumentNullException(nameof(entity));
try
{
var dbEnt = _context.Set<TEntity>().Where(c => c.Id == entity.Id).First();
dbEnt = entity;
dbEnt.UpdatedBy = GetCurrentUser();
dbEnt.DateUpdated = DateTime.Now;
_context.SaveChanges();
}
catch (DbUpdateException exception)
{
throw new Exception(GetFullErrorTextAndRollbackEntityChanges(exception), exception);
}
//-----other methods for insert and get working fine----
}
There are also other methods in this class for insert
and get
are working fine. Only this update method is not updating the entity and not throwing the exception.
UPDATE
I am facing similar problem but opposite in functioning here: Add() method adding duplicate rows for linked models in Code-First Entity Framework
I think these two have same reason of Change Tracking. But one is adding other is not updating.
The line...
var dbEnt = _context.Set<TEntity>().Where(c => c.Id == entity.Id).First();
...attaches an entity object to the context and returns a reference to this entity.
Then the line...
dbEnt = entity;
...replaces this reference by a reference to the entity
variable that enters the method. That is not the tracked entity object. You basically lost the reference to the tracked entity and it's impossible to change it any longer.
You should either attach entity
to the context and mark it as modified, or get dbEnt
as you already do and modify and save that object. Both methods have pros and cons, see here.