实体不使用代码优先方法更新

Entity not updating using Code-First approach

我有这个 class 用于数据库操作:

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----
}

此 class 中还有其他方法 insertget 工作正常。只有这个更新方法不更新实体并且不抛出异常。

更新

我遇到了类似的问题,但在这里的功能相反:

我认为这两个更改跟踪的原因相同。但是一个是添加另一个不是更新。

线...

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

...将实体对象附加到上下文和 returns 对此实体的引用。

然后行...

dbEnt = entity;

...将此引用替换为对进入方法的 entity 变量的引用。那是不是被跟踪的实体对象。您基本上丢失了对被跟踪实体的引用,并且无法再更改它。

您应该将 entity 附加到上下文并将其标记为已修改,或者像您已经做的那样获取 dbEnt 并修改并保存 that 对象.两种方法各有利弊,见here.

从 _context 获取实体后,更新新详细信息的所有字段并将实体状态设置为已修改

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();

如果您通过 Id 找到了您的实体

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

那为什么是这一行?

dbEnt = entity;

删除上面的行,因为它会删除对跟踪对象的引用。

谢谢大家。我从你的回答中得到了很多提示。 作为@GertArnold 和 @Colonel Software 的回答暗示我,我像这样修改了我的代码并且它起作用了:

//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();