2012-07-11 85 views
0

我的代碼與幾個嵌套循環大塊這需要在數據庫中更新最終多條記錄。我想盡量減少實體框架的SaveChanges()調用次數。另請注意,我們正在使用存儲庫模式。我應該期待什麼持續性的行爲,當在這種情況下

基本上我迭代的集合,需要更新兩個集合中,並在每次迭代中,從數據庫中檢索和語境通過從集合中項的另一對象的項目。

示例代碼:

foreach (var outer in outerList) 
      { 
       obj = unit.GetRepository<MyObj>().Get(s => 
        s.id = myId 
        ).SingleOrDefault(); 

       obj.value += outer.value;      
       outer.objId = obj.objId; 

       unit.GetRepository<MyOuterObj>().Update(outerObj); 
       unit.GetRepository<MyObj>().Update(obj);      
      } 
      unit.Save(); 

來更新(調用)執行以下操作:

public virtual void Update(T entityToUpdate) 
    { 
     if(entityToUpdate is AuditModelBase) 
     { 
      var model = entityToUpdate as AuditModelBase; 
      model.UpdatedAt = DateTime.UtcNow; 
     } 

     DbSet.Attach(entityToUpdate); 
     Context.Entry(entityToUpdate).State = EntityState.Modified; 
    } 

而且調用保存()當然下面執行:

_context.SaveChanges(); 

所以我的問題是,因爲我每次通過循環將obj重新賦值爲不同的值,我是否需要Save() foreach循環以便所有「obj」實例持續存在。或者DbSet.Attach(obj)確保每個單獨的實例都被更新,無論我在循環中如何處理對象。

也許更好的方式來問這個是:

鑑於它看起來像裝()是傳址引用,以便因此只有我最後OBJ將被更新,有什麼用EF最佳實踐完成這種事情(不包括直接調用SQL的選項)?

+0

所以,你寫的所有代碼,但你想知道它是否會奏效。你有沒有考慮過只是執行它並發現? – Servy 2012-07-11 19:56:27

+0

你在問這個問題:「這個特定的代碼段是否工作?」最好通過運行來解決。它只調用一次更新,所以你不會想出任何更少的東西。這個問題是:「這個工作法典是不是很好的做法,還是它可以提高效率?」是代碼審查的問題。 – Servy 2012-07-11 20:37:41

回答

0

我不認爲你不必擔心。一旦你在你的物體上撥打Attach,你是否保留自己的引用並不重要;它應該沒問題。

需要記住的是,您的物體的壽命長達,某人。所以,按理說,調用Attach會導致你的DbSet引用您的對象,它甚至還活着後,您不引用它了自己從而保持。

然而,做的最好的事情,在我看來,就是隻要給它一個嘗試,看看會發生什麼!

+0

是的,這是按照您在各種情況下所建議的方式工作的,並且更好的是,上下文會自動追蹤並執行對象之間關係的修復。因此,在併發不是主要問題的情況下,儘可能晚地調用Save()似乎是非常可行的。非常感謝您的幫助! – Shane 2012-07-12 20:00:19

+0

好吧,事實證明,是的,有一個參考,但不是副本。因此,在我上面的示例中,由於每次通過循環都將obj賦值給一個新對象,因此一切都很好。但是,不能做的是重複使用同一個對象,將它傳遞給Attach(),並期望存儲庫中有實例。對於有經驗的EF開發人員來說也許是顯而易見的,但不一定直觀來自舊的「commit to db」世界。我曾預料它的行爲有點像db的內存緩存表示,但事實並非如此。 – Shane 2012-07-13 15:37:46

相關問題