2012-06-13 32 views
1

現有的片段EF4的SaveChanges如何避免內存不足的異常

foreach (var ownerCandidates in ownerToCandidatesDictionary) 
    { 
    foreach (var candidate in ownerCandidates.Value) 
    { 
     transactionEntities.AddToSomeEntity(someObject) 
    } 
    } 
       transactionEntities.SaveChanges(System.Data.Objects.SaveOptions.AcceptAllChangesAfterSave); 

是重寫

int i = 0 ; 
    foreach (var ownerCandidates in ownerToCandidatesDictionary) 
    { 
     foreach (var candidate in ownerCandidates.Value) 
     { 
      transactionEntities.AddToSomeEntity(someObject) 
      } 
      if (i++ % 1000 == 0) 
      { 
       transactionEntities.SaveChanges(System.Data.Objects.SaveOptions.AcceptAllChangesAfterSave); 
      } 
    } 

transactionEntities.SaveChanges(System.Data.Objects.SaveOptions.AcceptAllChangesAfterSave); 

爲我們提供了成功的計劃終止的情況下相同的功能?我關心的是我們一直在添加的功能,SaveChanges在循環中的作用僅僅與自從上一次SaveChanges之後添加的功能一起使用。我們在這裏批量儲存嗎?如果不是這種情況如何原始片段可以被改變,以避免

12/06/2012 7:50:37 PM : System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. 
    at System.Data.Mapping.Update.Internal.Propagator.Project(DbProjectExpression node, PropagatorResult row, TypeUsage resultType) 
    at System.Data.Mapping.Update.Internal.Propagator.Visit(DbProjectExpression node) 
    at System.Data.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor) 
    at System.Data.Mapping.Update.Internal.Propagator.Propagate(UpdateTranslator parent, EntitySet table, DbQueryCommandTree umView) 
    at System.Data.Mapping.Update.Internal.UpdateTranslator.<ProduceDynamicCommands>d__0.MoveNext() 
    at System.Linq.Enumerable.<ConcatIterator>d__71`1.MoveNext() 
    at System.Data.Mapping.Update.Internal.UpdateCommandOrderer..ctor(IEnumerable`1 commands, UpdateTranslator translator) 
    at System.Data.Mapping.Update.Internal.UpdateTranslator.ProduceCommands() 
    at System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter adapter) 
    at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache) 
    at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) 

回答

6

到的SaveChanges後續調用()將不會有任何影響,如果改變不是()以前的SaveChanges後設置的實體作出。 SaveChanges()後面的數據庫是新批處理。使用EntityFramework進行大量插入時,批處理是克服OutOfMemoryException的選項。其實SaveChanges()應該只調用一次,但在你的情況下,由於數據很大,它必須分成批次。

同時在批量添加實體以顯着提高性能時,通過將AutoDetectChangesEnabled設置爲false,臨時禁用自動檢測更改。 Here is the infocontext.Configuration.AutoDetectChangesEnabled = false;

+0

但是,我包括的代碼片段,代碼片段2 - 你看到批處理。 – MicMit

+1

是的,行'if(i ++%1000 == 0)'批量生產。每批1000個刀片。 –