我实现了类似的解决方案,我们可以通过EF Core保存数据来修改创建和更新的日期,如Populate Created and LastModified automagically in EF Core所示。
void OnEntityStateChanged(object sender, EntityStateChangedEventArgs e)
{
if (e.NewState == EntityState.Modified && e.Entry.Entity is IHasCreationLastModified entity)
entity.LastModified = DateTime.Now;
}
起初我以为只有在调用SaveChanges()
时才会触发。但显然它也被称为Entry()
// Get entity
var student = _dbContext.Students.Find(studentId);
// Modify student object
student.Name = "New student name";
// Called Entry(), trigger ChangeTracker.StateChanged
var entry = _dbContext.Entry(student);
// Doesn't trigger ChangeTracker.StateChanged
_dbContext.SaveChanges();
我发现当调用ChangeTracker.StateChanged
时会触发_dbContext.Entry(student)
。然后当调用_dbContext.SaveChanges()
时它不再被触发。它也通过了if (e.NewState == EntityState.Modified && e.Entry.Entity is IHasCreationLastModified entity)
以上的条件。
我假设为什么在调用SaveChanges()
时不再触发它,因为在调用Entity()
之后没有对实体进行新的更新。
这导致在调用LastModified
时分配.Entry(student)
属性,而不是在调用.SaveChanges()
时。
在上面的场景中调用LastModified
时,有没有办法只更新SaveChanges
属性?
我建议您可以在dbContext中覆盖SaveChanges
方法。你可以参考下面我经常使用的代码。
public class ForumContext : DbContext
{
public ForumContext(DbContextOptions<ForumContext> options) : base(options)
{
}
//other settings
public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
foreach (var entry in ChangeTracker.Entries())
{
switch (entry.State)
{
case EntityState.Added:
((BaseEntity)entry.Entity).AddedDate = DateTime.Now;
((BaseEntity)entry.Entity).LastModified = DateTime.Now;
break;
case EntityState.Modified:
((BaseEntity)entry.Entity).LastModified = DateTime.Now;
break;
case EntityState.Deleted:
entry.State = EntityState.Modified;
entry.CurrentValues["IsDeleted"] = true;
break;
}
}
return base.SaveChanges(acceptAllChangesOnSuccess);
}