I have > 67000 records coming to my system from another source. After applying business rules to those records I have to store them to the database. I use following code for doing that:
using (var context = new MyEntities())
{
var importDataInfo = context.ImportDataInfoes.First(x => x.ID == importId);
importedRecords.ForEach(importDataInfo.ValuationEventFulls.Add);
context.SaveChanges();
}
After executing code I am getting following error (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)
I am using EF 4.0.
My question is there is limitation on number of records to save? What is the best practice to save big number of records (save them in chunks? what about transactions?).
Thanks everybody in advance.
You would probably want to send that data down in batches of probably 1024 records at a time.
You could wrap the loop that batches the records in a transaction so you could rollback the entire sequence if desired. Do note that this transaction will most likely escalate to a distributed transaction.
Distributed transactions can only be applied against a server that has the Microsoft Distributed Transaction Coordinator (MS-DTC) service running. There is a notable performance penalty when working distributed transactions.