DbContext SaveChanges() - Откриване на актуализирани обекти

Замених метода SaveChanges() в класа DbContext на Entity Framework 4.1.

Моята замяна изглежда така:

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() кой от двата обекта действително е актуализирал ред в базата данни и кой в ​​крайна сметка не е бил наистина променен?


person FantasticJamieBurns    schedule 14.11.2011    source източник


Отговори (1)


Това е начинът, по който го правим нашия код. Активирано е отложено зареждане и създаване на прокси.

Имайте предвид, че когато създаването на прокси сървър е активирано, 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;
          }
      }
  }
person np-hard    schedule 14.11.2011
comment
Нито създаването на прокси, нито отложеното зареждане са активирани. Ще ми пука и в двата случая! Прилагам одит към всички актуализации на базата данни и имам бизнес изискване само онези обекти, които действително водят до промяна в базата данни, да се регистрират. Бих могъл да опитам RowVersion, но ми се струва грешно да добавя колона към база данни само за тази цел. Мога също така първо да заредя основния обект от базата данни и да сравня. Просто изглежда, че DbContext знае, че само 1 е актуализиран, чудех се дали има начин само от контекста да разбера кой. - person FantasticJamieBurns; 15.11.2011
comment
актуализирах отговора си с примерен код. BusinessBase е нашият базов клас за всички обекти. - person np-hard; 15.11.2011