1

レコードの巨大なデータセット (数十万単位) を取り込み、アトミック トランザクションで一度に 1 つずつ、それぞれのフィールドを更新する必要があります。それらのレコードは互いに無関係であり、数十万すべてを盲目的に更新したくありません (このテーブルにはビューとインデックスがあり、非常に禁止されています)。巨大なトランザクションを実行せずにこれを機能させる唯一の方法は次のとおりです (コンテナーはカスタム ObjectContext への参照です)。

var expiredWorkflows = from iw in container.InitiatedWorkflows
where iw.InitiationStatusID != 1 && iw.ExpirationDate < DateTime.Now
select iw.ID;

foreach (int expiredWorkflow in expiredWorkflows)
container.ExecuteStoreCommand("UPDATE dbo.InitiatedWorkflow SET InitiationStatusID = 7 WHERE ID = @ID", new SqlParameter() { ParameterName = "@ID", Value = expiredWorkflow.ToString() } );

それぞれをループして、コンテナーを介してフィールドを更新してから SaveChanges() を呼び出してみましたが、すべてが 1 つのトランザクションとして実行されます。foreach ループで SaveChanges() を呼び出してみましたが、トランザクション例外がスローされました。ObjectContext を使用してやろうとしていることを行う方法はありますか? (上記の選択は、ID だけでなく完全なオブジェクトを返すように変更されます):

foreach (var expiredWorkflow in expiredWorkflows)
expiredWorkflow.InitiationStatusID = 7

container.SaveChanges(SaveOptions.OneAtATime);
4

1 に答える 1

0

一般的に言えば、実行する必要がある操作が、上記のコードが示唆する種類の UPDATE と同じくらい単純である場合、これはバックエンド データベースではるかに適切に実行される種類の操作です。変更が必要な行のみを選択する方法。Entity Framework は、ストアド プロシージャが最適であることが多い大規模な一括処理操作ではなく、メモリに簡単に読み込んで調整できる小規模から中規模のオブジェクト セットを操作することを目的としています。EF は確かにこれらの大きな操作を実行できますが、行ごとに 1 つの SQL ステートメントを実行するには、はるかに時間がかかります。

于 2012-07-25T13:08:57.467 に答える