1

既存のフラグメント

foreach (var ownerCandidates in ownerToCandidatesDictionary)
  {
    foreach (var candidate in ownerCandidates.Value)
    {
       transactionEntities.AddToSomeEntity(someObject)
    }
  }
                transactionEntities.SaveChanges(System.Data.Objects.SaveOptions.AcceptAllChangesAfterSave);

に書き直しています

    int i = 0 ; 
    foreach (var ownerCandidates in ownerToCandidatesDictionary)
    {
         foreach (var candidate in ownerCandidates.Value)
         {
             transactionEntities.AddToSomeEntity(someObject)
          }
          if ( i++ % 1000 == 0 ) 
          {
               transactionEntities.SaveChanges(System.Data.Objects.SaveOptions.AcceptAllChangesAfterSave);
          } 
    }

transactionEntities.SaveChanges(System.Data.Objects.SaveOptions.AcceptAllChangesAfterSave);

プログラムが正常に終了した場合に同じ機能を提供しますか?追加し続ける私の懸念は、ループ内のSaveChangesは、以前のSaveChanges以降に追加されたものでのみ機能しますか。ここにバッチで保存できますか?そうでない場合は、回避するために元のフラグメントを変更する方法

12/06/2012 7:50:37 PM : System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
   at System.Data.Mapping.Update.Internal.Propagator.Project(DbProjectExpression node, PropagatorResult row, TypeUsage resultType)
   at System.Data.Mapping.Update.Internal.Propagator.Visit(DbProjectExpression node)
   at System.Data.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
   at System.Data.Mapping.Update.Internal.Propagator.Propagate(UpdateTranslator parent, EntitySet table, DbQueryCommandTree umView)
   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)
4

1 に答える 1

6

前のSaveChanges()の後に設定されたエンティティに変更が加えられていない場合、その後のSaveChanges()の呼び出しは効果がありません。SaveChanges()の後、データベースに入るのは新しいバッチです。バッチ処理は、EntityFrameworkを使用した大量の挿入中にOutOfMemoryExceptionを克服するためのオプションです。実際には、SaveChanges()は1回だけ呼び出す必要がありますが、データが膨大であるため、バッチに分割する必要があります。

また、エンティティを一括で追加してパフォーマンスを大幅に向上させる場合は、AutoDetectChangesEnabled falseに設定して、変更の自動検出を一時的に無効にします。ここに情報がありますcontext.Configuration.AutoDetectChangesEnabled = false;

于 2012-06-13T05:38:39.577 に答える