results = (from r in results
where r.Buildings.Any(x=>x.StructuralElements.Any(s=>s.VALUE == Model.Bedrooms.ToString() && s.CATEGORY=="RM"))
select r);
我想我在这里错过了加入。但也许他们暗示了?执行运行这么久我无法做一个手表来评估生成的查询表达式
答案 0 :(得分: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))
你明白为什么会这么糟糕吗?对于每个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();
这是PlayMany运算符(它将一个集合并将子集合展平为一个集合)。