Entity not updating using Code-First approach

天涯浪子 提交于 2019-12-11 07:26:41

问题


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.


回答1:


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.




回答2:


After getting entity from _context, update all fields from new detail and set entity state to modified

var dbEnt = _context.Set<TEntity>().Where(c => c.Id == entity.Id).First();
dbEnt.Name = entity.Name;
...
...
...
dbEnt.UpdatedBy = GetCurrentUser();
dbEnt.DateUpdated = DateTime.Now;
_context.Entry(dbEnt).State = EntityState.Modified;
_context.SaveChanges();



回答3:


If you have found your entity via Id

var dbEnt = _context.Set<TEntity>().Where(c => c.Id == entity.Id).First();

then why this line?

dbEnt = entity;

Remove the above line as it will remove the reference to the tracked object.




回答4:


Thank you everyone. I received a lots of hint from your answers. As @GertArnold and @Colonel Software's answer hinted me I modified my code like this and it worked:

//Assigning BaseModel properties
entity.CreatedBy = dbEnt.CreatedBy;
entity.UpdatedBy = GetCurrentUser();
entity.DateUpdated = DateTime.Now;
entity.DateCreated = dbEnt.DateCreated;

//Changing entity states
_context.Entry(dbEnt).State = EntityState.Detached;
_context.Entry(entity).State = EntityState.Modified;

_context.SaveChanges();


来源:https://stackoverflow.com/questions/56302611/entity-not-updating-using-code-first-approach

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!