2017-04-27 58 views
0

我正在運行一個將事件插入帶有實體框架的數據庫的批處理作業。總大小不一,但大約有350萬個事件是正常的。該列表被拆分成60-500k個事件組,然後添加到數據庫中。System.OutOfMemoryException實體框架6 for db.SaveChanges

但是,當大約一百萬個事件被添加時,我得到了System.OutOfMemoryException並且必須重新開始。所以要完成這個程序,現在必須運行3-4次。如何在調用SaveChanges()後清除我的數據庫對象,這樣不會發生?

public DbSet<Events> Events { get; set; } 
... 
var groupedList = list.GroupBy(x => x.Import.FileName); 
var db = new ApplicationDbContext(); 

foreach (var group in groupedList) 
{ 
    db.Events.AddRange(group); 
    db.SaveChanges(); 
} 

堆棧跟蹤:

System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown. 
at System.Data.Entity.Core.Mapping.Update.Internal.KeyManager.GetPrincipals(Int32 identifier) 
at System.Data.Entity.Core.Mapping.Update.Internal.DynamicUpdateCommand..ctor(TableChangeProcessor processor, UpdateTranslator translator, ModificationOperator modificationOperator, PropagatorResult originalValues, PropagatorResult currentValues, DbModificationCommandTree tree, Dictionary`2 outputIdentifiers) 
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateCompiler.BuildInsertCommand(PropagatorResult newRow, TableChangeProcessor processor) 
at System.Data.Entity.Core.Mapping.Update.Internal.TableChangeProcessor.CompileCommands(ChangeNode changeNode, UpdateCompiler compiler) 
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.<ProduceDynamicCommands>d__a.MoveNext() 
at System.Linq.Enumerable.<ConcatIterator>d__58`1.MoveNext() 
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateCommandOrderer..ctor(IEnumerable`1 commands, UpdateTranslator translator) 
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.ProduceCommands() 
at System.Data.Entity.Core.Mapping.Update.Internal.UpdateTranslator.Update() 
at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.<Update>b__2(UpdateTranslator ut) 
at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update[T](T noChangesResult, Func`2 updateFunction) 
at System.Data.Entity.Core.EntityClient.Internal.EntityAdapter.Update() 
at System.Data.Entity.Core.Objects.ObjectContext.<SaveChangesToStore>b__35() 
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) 
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesToStore(SaveOptions options, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction) 
at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass2a.<SaveChangesInternal>b__27() 
at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation) 
at System.Data.Entity.Core.Objects.ObjectContext.SaveChangesInternal(SaveOptions options, Boolean executeInExistingTransaction) 
at System.Data.Entity.Core.Objects.ObjectContext.SaveChanges(SaveOptions options) 
at System.Data.Entity.Internal.InternalContext.SaveChanges() 
at System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 
at System.Data.Entity.DbContext.SaveChanges() 
at Project.Program.Main(String[] args) in C:\Users\oscar\Documents\Solution\Project\Program.cs:line 135 
+0

您是否嘗試重新創建ApplicationDbContext?這意味着在foreach循環中移動新的ApplicationDbContext()。 – Gimly

+0

處理它並新建一個新的DbContext。 – spender

+0

[SaveChanges上實體框架4內存不足]的可能重複(http://stackoverflow.com/questions/15941471/entity-framework-4-out-of-memory-on-savechanges) – Gimly

回答

4

將一個批次後,你應該重新創建DbContext清除ChangeTracker。這不僅應該解決你的記憶問題,還應該讓事情更快一點。類似於

foreach (var group in groupedList) 
{ 
    using(var db = new MyDbContext()){ 
    db.Events.AddRange(group); 
    db.SaveChanges(); 
    } 
}