[英]System.OutOfMemoryException Entity Framework 6 for db.SaveChanges
I'm running a batch job of inserting events into a database with entity framework.我正在使用实体框架运行将事件插入数据库的批处理作业。 Total size varies but around 3.5 million events are normal.总规模各不相同,但大约 350 万个事件是正常的。 This list is split up into groups of 60-500k events that are then added to the database.此列表分为 60-500k 事件组,然后添加到数据库中。
However when around one million events have been added I get System.OutOfMemoryException
and have to start over.但是,当添加了大约一百万个事件时,我得到System.OutOfMemoryException
并且必须重新开始。 So to complete the program it has to be run 3-4 times now.因此,要完成该程序,它现在必须运行 3-4 次。 How can I clear my db object after SaveChanges()
has been called so this won't happen?如何在调用SaveChanges()
后清除我的数据库 object 以免发生这种情况?
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();
}
Stack trace:堆栈跟踪:
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
After inserting one batch you should recreate your DbContext
to clear the ChangeTracker
. 插入一批后,您应该重新创建DbContext
以清除ChangeTracker
。 This should not only fix your memory issue, but also make things a bit faster. 这不仅可以解决您的内存问题,还可以使处理速度更快。 Something like 就像是
foreach (var group in groupedList)
{
using(var db = new MyDbContext()){
db.Events.AddRange(group);
db.SaveChanges();
}
}
You could also just call.你也可以打电话。
_context.ChangeTracker.Clear();
This will clear the change tracker and is faster then creating a new context.这将清除更改跟踪器,并且比创建新上下文更快。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.