ChangeTracker.StateChanged из DbContext срабатывает при вызове .Entry () - PullRequest
0 голосов
/ 20 марта 2019

Я реализовал аналогичное решение о том, как мы можем изменить созданную и обновленную дату при сохранении данных через EF Core, как это предлагается здесь Автоматически заполнить Созданный и LastModified в 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 вызывается по сценарию выше?

1 Ответ

1 голос
/ 20 марта 2019

Я предлагаю вам переопределить метод SaveChanges в вашем dbContext.Вы можете ссылаться на приведенный ниже код, который я обычно использую.

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);
    }
...