簡體   English   中英

實體框架(EF)OutOfMemoryException

[英]Entity Framework (EF) OutOfMemoryException

我有來自其他來源的> 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。

我的問題是要保存的記錄數量有限制嗎? 保存大量記錄的最佳做法是什么(將它們保存在塊中?交易怎么樣?)。

提前謝謝大家。

您可能希望一次批量發送大約1024條記錄的數據。

您可以包裝在事務中批處理記錄的循環,以便您可以根據需要回滾整個序列。 請注意,此事務很可能會升級為分布式事務。

分布式事務只能應用於運行Microsoft分布式事務處理協調器(MS-DTC)服務的服務器。 在分布式事務處理時,性能會受到顯着影響。

通常,.NET僅限於在單個集合或其他對象中處理2GB內存。 這是因為即使在64位環境中,索引器也使用32位整數(最大值為20億並且更改)。 即使對於像整數這樣的簡單數據類型,單個int的大小意味着只能在單個數組中存儲5億個int。 對於像結構這樣的較大值類型,集合的最大元素數量非常小。

如果你處於像Windows XP這樣的32位環境中,那么它的限制甚至更低; 整個程序的最大內存空間不能超過2GB。 這對像你這樣的ETL有一些相當高的限制,我不會對你的程序內存耗盡試圖同時處理67k內存中的記錄感到驚訝。

解決方案是盡可能小批量處理記錄。 嘗試根據ID構建一個語句,返回前100條記錄,其中ID(希望自動生成)大於您已檢索的最大ID。 處理完記錄后,處理它(或者只是孤立它並讓GC完成它的工作)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM