0
results = (from r in results 
where r.Buildings.Any(x=>x.StructuralElements.Any(s=>s.VALUE == Model.Bedrooms.ToString() && s.CATEGORY=="RM"))
select r);

ここで結合が欠落していると思います。しかし、おそらくそれらは暗示されていますか?実行に時間がかかりすぎて、生成されたクエリ式を評価するための監視を行うことができません

4

1 に答える 1

0

このクエリの最大の問題は次のとおりです。

--@p1 = Models.Bedrooms.ToString()
--@p2 = "RM"
SELECT * FROM Results r WHERE EXISTS
    (SELECT x.* FROM Results tr JOIN Buildings x ON tr.SomeID=x.SomeID WHERE tr.ID = r.ID AND EXISTS
        (SELECT s.* FROM StructuralElements s JOIN Buildings tx ON tx.OtherID = s.OtherID WHERE tx.ID=x.ID AND s.VALUE = @p1 AND s.Category = @p2))

なぜこれが悪いのか分かりますか?すべての結果に対して、サブクエリを実行しています (それ自体がサブクエリを実行しています)。これらのネストされたサブクエリのために、ルート レベル (結果と建物) で何かを追加し始めると、時間/処理が指数関数的に増加します。最善の策は、完了後に結合を使用して個別のr値を取得することです。SQL は次のようになります。

SELECT DISTINCT 
    r.* 
FROM
    Results r
    INNER JOIN Buildings x ON x.SomeID = r.SomeID
    INNER JOIN StructuralElements s ON s.OtherID = r.OtherID
WHERE
    s.VALUE = @p1 AND s.CATEGORY = @p2

これが機能する理由は、結合するときに、結合するものが複数ある場合、元の行が複製されるためです。次の図は、

IDs
R     X     S
1     -     -
Join X
1     1     -
1     2     -
1     3     -
Join S
1     1     1
1     1     2
1     2     5
1     2     6

あなたの基準S=2を満たしていると仮定すると、(フォームで) 行とが返されます。この場合、固有のものを取得すると、 のみが返されます。これは、達成しようとしていることです。EF を使用すると、リレーションシップは既に存在するため、追加の操作は必要ありません。フィルター処理しようとしている列を参照するだけです。S=6R,X,S1,1,21,2,6rR=1

results =  (from r in results
            from x in r.Buildings
            from s in x.StructuralElements
            where s.VALUE == Model.Bedrooms.ToString() && s.CATEGORY=="RM"
            select r).Distinct();

これは、使用中の SelectMany 演算子です (コレクションを取得し、サブコレクションを 1 つのコレクションにフラット化します)。

于 2012-06-05T14:43:04.210 に答える