results = (from r in results
where r.Buildings.Any(x=>x.StructuralElements.Any(s=>s.VALUE == Model.Bedrooms.ToString() && s.CATEGORY=="RM"))
select r);
我想我在這裏缺少連接。但也許它們是隱含的?執行遇到這麼久,我不能做一個表來評估生成的查詢表達式使用linq指定子查詢子查詢的正確方法
results = (from r in results
where r.Buildings.Any(x=>x.StructuralElements.Any(s=>s.VALUE == Model.Bedrooms.ToString() && s.CATEGORY=="RM"))
select r);
我想我在這裏缺少連接。但也許它們是隱含的?執行遇到這麼久,我不能做一個表來評估生成的查詢表達式使用linq指定子查詢子查詢的正確方法
此查詢中最大的問題是這樣的:
[email protected] = Models.Bedrooms.ToString()
[email protected] = "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))
你明白爲什麼這會是壞?對於每個Result,你都運行一個子查詢(它本身正在運行一個子查詢)。由於這些嵌套的子查詢,當您開始在根級別(結果和建築物)添加事物時,這將成爲時間/處理的指數增長。您最好的選擇是在完成後使用連接並獲取不同的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
和S=6
滿足條件,那麼它會返回(在R,X,S
形式)行1,1,2
和1,2,6
。在這種情況下獲取截然不同的r
將只返回R=1
,這正是您要完成的。使用EF的關係已經存在,所以你不需要做任何額外的東西,只是引用你想過濾的列:
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(這需要一個集合並將子集收集到一個集合中)。
你似乎已經明白我在問什麼了,我以爲EF會處理很多煩瑣的工作,讓我測試一下 –
沒問題,如果關係設置不正確,那麼'SelectMany'最終會成爲查詢世界中的'FROM TableA,TableB',這就是爲什麼EF(和L2S)處理關係你將會把這些引用轉換成連接。一般來說,當我處理嵌套關係時(甚至在SQL世界中),我會說盡量遠離'Any'。 – SPFiredrake
我不知道我在做什麼。:\ –
「results =(from r in results」呃,讓我們看看以前的查詢部分 –