我从另一个来源接收到超过67000条记录。在应用业务规则后,我需要将它们存储到数据库中。我使用以下代码进行操作:
using (var context = new MyEntities())
{
var importDataInfo = context.ImportDataInfoes.First(x => x.ID == importId);
importedRecords.ForEach(importDataInfo.ValuationEventFulls.Add);
context.SaveChanges();
}
执行代码后,我得到了以下错误(OutOfMemoryException)。
Error in executing code|Exception of type 'System.OutOfMemoryException' was thrown.* at System.Data.Mapping.Update.Internal.KeyManager.<WalkGraph>d__5.MoveNext()
at System.Data.Mapping.Update.Internal.KeyManager.GetPrincipalValue(PropagatorResult result)
at System.Data.Mapping.Update.Internal.UpdateCompiler.GenerateValueExpression(EdmProperty property, PropagatorResult value)
at System.Data.Mapping.Update.Internal.UpdateCompiler.BuildSetClauses(DbExpressionBinding target, PropagatorResult row, PropagatorResult originalRow, TableChangeProcessor processor, Boolean insertMode, Dictionary`2& outputIdentifiers, DbExpression& returning, Boolean& rowMustBeTouched)
at System.Data.Mapping.Update.Internal.UpdateCompiler.BuildInsertCommand(PropagatorResult newRow, TableChangeProcessor processor)
at System.Data.Mapping.Update.Internal.TableChangeProcessor.CompileCommands(ChangeNode changeNode, UpdateCompiler compiler)
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)
我正在使用EF 4.0。
我的问题是,是否有保存记录数量的限制?保存大量记录的最佳实践是什么(将它们分块保存?事务如何处理?)。
提前感谢大家。
if(i%1024 == 0) context.SaveChanges()
。然后你仍然需要在循环外部进行1次最终的savechanges调用,因为你可能没有一个完美的最后大小的批处理。当处理大型记录集时,你可能还想要查看yield return
运算符并使用可枚举对象来避免将整个记录集加载到内存中。 - Chris Marisic