我有用于数据库操作的此类:
process.start(path & ListView1.SelectedItems(0).Text)
此类中的其他方法也可以使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----
}
和insert
正常工作。仅此更新方法不会更新实体,也不会引发异常。
答案 0 :(得分:1)
从_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();
答案 1 :(得分:0)
线路...
var dbEnt = _context.Set<TEntity>().Where(c => c.Id == entity.Id).First();
...将实体对象附加到上下文,并返回对该实体的引用。
然后一行...
dbEnt = entity;
...通过引用进入该方法的entity
变量的引用替换此引用。那不是被跟踪实体对象。您基本上失去了对被跟踪实体的引用,因此无法再对其进行更改。
您应该将entity
附加到上下文并将其标记为已修改,或者像现在一样获取dbEnt
并修改并保存那个对象。两种方法都有优缺点,请参见here。
答案 2 :(得分:0)
如果您通过ID找到了您的实体
var dbEnt = _context.Set<TEntity>().Where(c => c.Id == entity.Id).First();
那为什么要这行呢?
dbEnt = entity;
删除上面的行,因为它将删除对跟踪对象的引用。
答案 3 :(得分:-1)
谢谢大家。您的回答给我很多提示。 作为@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();