DbContext SaveChanges () - обнаружение обновленных объектов - PullRequest
6 голосов
/ 15 ноября 2011

Я переопределил метод SaveChanges () в классе Entity Framework 4.1 DbContext.

Мое переопределение выглядит так:

public override int SaveChanges() {

    IEnumerable<DbEntityEntry> modifiedEntityEntries = ChangeTracker.Entries().Where( e => e.State == EntityState.Modified );

    Debug.Assert( modifiedEntityEntries.Count() == 2 );

    int savedChanges = base.SaveChanges();

    Debug.Assert( savedChanges == 1 );

    // HELP! At this point, how do I tell Which of the two "Modified" entities actually updated a row in the database?

    return savedChanges;

}

Предположим, что в контексте есть 2 объекта,и оба помечены как измененные (EntityState.Modified).Один из них был изменен и отличается от базовой строки базы данных.Другая на самом деле не отличается от базовой строки базы данных, она просто помечена как таковая.

Как мне сказать после вызова SaveChanges (), какая из двух сущностей фактически обновила строкув базе данных, и какой из них не был действительно изменен в конце концов?

1 Ответ

3 голосов
/ 15 ноября 2011

Вот так мы делаем наш код. Ленивая загрузка и создание прокси включены.

Обратите внимание, что когда включено создание прокси, EF будет знать, какое свойство изменилось, вам не нужно переходить в базу данных. Единственное место, которое EF не знал бы, это если какой-то другой контекст изменил строку (ошибка параллелизма), чтобы избежать использования столбца / свойства RowVersion

В конструкторе:

  public DataContext()
            : base()
  {
      this.Configuration.ProxyCreationEnabled = true;
      this.Configuration.LazyLoadingEnabled = true;
      var objectContext = ((IObjectContextAdapter)this).ObjectContext;
      objectContext.SavingChanges += new EventHandler(objectContext_SavingChanges);
  }

  private void objectContext_SavingChanges(object sender, EventArgs e)
  {
      var objectContext = (ObjectContext)sender;
      var modifiedEntities =
            objectContext.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added
            | System.Data.EntityState.Modified);

      foreach (var entry in modifiedEntities)
      {
          var entity = entry.Entity as BusinessBase;
          if (entity != null)
          {
              entity.ModDateTime = DateTime.Now;
              entity.ModUser = Thread.CurrentPrincipal.Identity.Name;
          }
      }
  }
...