2012-10-04 53 views
6

跟隨Julia Lermas在保持追蹤變化的N層解決方案中的書'DbContext',我爲每個實體提供了一個State屬性和一個OriginalValues字典(通過IObjectWithState)。在構造實體之後,我將原始值複製到此字典中。請參閱本書的樣品(4-23):DbContext.Entry性能問題

public BreakAwayContext() 
{ 
    ((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized += (sender, args) => 
    { 
     var entity = args.Entity as IObjectWithState; 
     if (entity != null) 
     { 
     entity.State = State.Unchanged; 
     entity.OriginalValues = BuildOriginalValues(this.Entry(entity).OriginalValues); 
     } 
    }; 
} 

在ObjectMaterialized事件被抓住了BreakAwayContext(從繼承的DbContext)的構造函數。爲了檢索實體的原始值,通過調用this.Entry(entity)從上下文中檢索DbEntityEntry。這個呼叫正在放慢這個過程。此事件處理程序的80%時間用於此次調用。

有沒有更快的方法來檢索原始值或實體DbEntityEntry?

+0

您是否嘗試過使用其他建議來存儲更改後的值列表?我認爲存儲原始值會很昂貴,所以在我的多層(多平臺)解決方案中,我存儲了包含更改屬性的逗號分隔列表(在Delphi中,使用.Net中的T4模板重寫Delphi中每個屬性的設置器首先)。在DAL中,實體(或DTO)發送更新時,我循環並將每個更改的屬性標記爲已修改。這並不能解釋檢索原始值的更快方法,但它會實現斷開的更改跟蹤。 – reckface

回答

12

Context.Entry()調用DetectChanges(),它取決於上下文中對象的數量並且可能非常慢。在你的情況下,你可以用更快的版本來替換((IObjectContextAdapter) ctx).ObjectContext.ObjectStateManager.GetObjectStateEntry(obj);

+0

謝謝!我只是將我的代碼換成了使用替代方法。我的狀態調用時間從8秒到.003 – BigJoe714

+0

令人驚歎!從4秒到幾乎0的狀態呼叫!我用((IObjectContextAdapter)ctx).ObjectContext.ObjectStateManager.GetObjectStateEntry(obj).ChangeState(EntityState.Modified); –