调用.Entry()时会触发DbContext的ChangeTracker.StateChanged

问题描述 投票:0回答:1

我实现了类似的解决方案,我们可以通过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属性?

c# asp.net-core entity-framework-core ef-core-2.1
1个回答
1
投票

我建议您可以在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);
    }
© www.soinside.com 2019 - 2024. All rights reserved.