1

私はEF、データベースを最初に持っています。、、の3つのモデルクラスABありCます。モデルAには、とのm2m関係がBあり、との関係Bはm2mCです。

A関連するBとのサブセットをリストしていCます。

テストされた環境では、サブセットに約20のモデルがあり、関連するモデルAはごくわずかであり、関連するB場合は、ほとんどの場合1つです。

モデルBには常に1つの関連がありCます。C将来的には1つに関連するものが増えるので、変更したくありませんB

私の最初のアプローチは次のとおりです。

var listA = new Entities(...).As.Where(...).ToList();
foreach (var objA in listA){
    var listC = objA.Bs.ToList().Select(b => b.FirstOrDefault(c => ...)).ToList();
}

約164msかかりました-かなり長いです。

だから私はそれを最適化することについて考えました。

ご覧のとおり、最初の行IQueryable<A>はに変更されていList<A>ます。この瞬間、クエリが実行されると思います。

BsforACforを取得したい場合はB、別のクエリが実行されると思います。

Includeそれから私はメソッドを検索して見つけました。2番目のアプローチでは、次のように使用しました。

var listA = new Entities(...).As.Include("Bs.Cs").Where(...).ToList();
foreach (var objA in listA){
    var listC = objA.Bs.ToList().Select(b => b.FirstOrDefault(c => ...)).ToList();
}

私の意見では、実行には約10ミリ秒かかるはずですが、現在は550ミリ秒かかります。

As関連Bsのないリストを作成しCsたところ、約10ミリ秒かかります。

私は何が間違っているのですか?

編集:申し訳ありませんが、CはBにFKを持っています。しかし、それは何も変わらないと思います。

4

2 に答える 2

0

DbContextが「デフォルトでtrue」の遅延読み込みをサポートしている場合、呼び出すたびにデータベースに多くのヒットが発生しobjA.Bs.ToList()ます。これは、最初のクエリb => b.FirstOrDefault(c => ...) にこれらのナビゲーションプロパティを含めなかったためですlistA

とにかくIncludeメソッドを使用してみてください

var listA = new Entities(...).As.Include("Bs").Include("Bs.Cs").Where(...).ToList();
于 2012-11-27T10:03:57.910 に答える
0

私の経験によると、関連するオブジェクトの明示的な読み込みは少し速くなります。オブジェクトのLoad()メソッドを使用してロードしてみて、IsLoadedを使用してすでにロードされているかどうかを確認してください。さらに、遅延読み込みをオフにし、接続を明示的に開くと役立つ場合があります。

次のようなものが役立つ場合があります。

var listA = from o in context where (...) select o;
foreach (var i in listA)
            {
                if (!i.Bs.IsLoaded)
                    i.Bs.Load();
                if (i.Bs != null)
                {
                    if (!i.Bs.Cs.IsLoaded)
                        i.Bs.Cs.Load();
                }

            }
于 2012-12-03T14:05:21.937 に答える