web-dev-qa-db-ja.com

セッションLINQ To Entityで実行中の他のスレッドがあるため、新しいトランザクションは許可されません

なぜこれが壊れる可能性があるかについてのアイデアはありますか?

foreach (var p in pp)
{
    ProjectFiles projectFile = (ProjectFiles)p;
    projectFile.Status = Constants.ProjectFiles_ERROR;
    projectFile.DateLastUpdated = DateTime.Now;
    context.SaveChanges();
}

この問題の回避策は、foreachループの前に一度に結果を取得することだと読みました。

しかし、私はそれをしませんでしたか? 「pp」は私の場合の結果のコレクションです

137
Nick LaMarca

pp変数はオブジェクトのコレクションではなく、オブジェクトを返すことができる列挙子です。列挙子を使用している間、ソースは開いたままにしておく必要があります。

ToListメソッドを使用して、コレクションへの列挙子を実現します。これにより、列挙子からすべてのアイテムが読み取られ、ソースへの接続が閉じられるため、他の目的で接続を使用できます。

foreach (var p in pp.ToList())
353
Guffa

起こっているのは、1つのSQL接続を使用してDBエンティティのコレクションを反復処理し、別の接続を使用して変更を保存しているということです。これは、クラスが基本的にdb接続の1つのインスタンスと「結婚」しており、別のインスタンスでは変更できないためです。

これを回避する方法は、コレクションを繰り返す前に.ToList()を呼び出すことです。

そして、コードを高速化するために、ループの終了後にcontext.SaveChanges()を一度だけ呼び出します。

9