4

データベースクエリに関して、コードのパフォーマンスを更新しようとしています。私が現在直面している問題は、各サブクエリの新しいコンテキストを取得する方法を見つけることができないように見えることです。

以下の簡略化されたコードを使用すると、「基になるプロバイダーがOpenで失敗しました」という一貫性のない生成が発生します。

using (var context = getNewContextObject())
{
    var result = new SomeResultObject();
    var parentQuery = context.SomeTable.Where(x => x.Name = "asdf");

    Parallel.Invoke(() =>
        {
            result.count1 = parentQuery.Where(x => x.Amount >= 100 & x.Amount < 2000).Count();
        }, () =>
        {
            result.count2 = parentQuery.Where(x => x.Amount < 100).Count();
        }
        , () =>
        {
            result.count3 = parentQuery.Where(x => x.Amount >= 2000).Count();
        }
    );

}

これまでのところ、これを回避する唯一の方法は、新しいコンテキストを使用して各subQueryのクエリ全体を再構築することであるようです。新しいコンテキストを使用して各クエリを下から上に構築することを回避する方法はありますか?代わりに、各サブクエリクエリを新しいコンテキストにアタッチすることはできますか?以下のようなものを探しています。

    Parallel.Invoke(() =>
        {
            var subQuery = parentQuery.Where(x => x.Amount >= 100 & x.Amount < 2000).Count();
            subQuery.Context = getNewContextObject();
            result.count1 = subQuery.Count();

        }, () =>
        {
            var subQuery = parentQuery.Where(x => x.Amount < 100).Count();
            subQuery.Context = getNewContextObject();
            result.count2 = subQuery.Count();
        }
        , () =>
        {
            var subQuery = parentQuery.Where(x => x.Amount >= 2000).Count();
            subQuery.Context = getNewContextObject();
            result.count3 = subQuery.Count();
        }
    );

}
4

1 に答える 1

7

これがあなたの問題にどのように正確に関連しているかはわかりませんが、EF機能はどれもスレッドセーフではないため、同じコンテキストインスタンスで複数のクエリを並行して実行すると、何らかの理由で爆発する可能性があります。たとえば、コンテキスト内の同じ接続プロパティにアクセスしますが、スレッドはお互いを認識しないため、他のスレッドへの接続を閉じたり、インスタンスを他の接続インスタンスに置き換えたりできます(並列実行する前に手動で接続を開くことができます)スレッドを作成し、すべてのスレッドが完了したら閉じますが、問題が1つだけである必要はありません)。

于 2011-05-19T21:20:29.637 に答える