results = (from r in results
where r.Buildings.Any(x=>x.StructuralElements.Any(s=>s.VALUE == Model.Bedrooms.ToString() && s.CATEGORY=="RM"))
select r);
我想我在这里缺少连接。但也许它们是隐含的?执行运行时间太长,我无法监视来评估生成的查询表达式
results = (from r in results
where r.Buildings.Any(x=>x.StructuralElements.Any(s=>s.VALUE == Model.Bedrooms.ToString() && s.CATEGORY=="RM"))
select r);
我想我在这里缺少连接。但也许它们是隐含的?执行运行时间太长,我无法监视来评估生成的查询表达式
此查询中最大的问题是:
--@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
并S=6
满足您的条件,那么它将返回(R,X,S
形式)行1,1,2
和1,2,6
. 在这种情况下,仅获得 distinctr
只会返回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 运算符(它接受一个集合并将子集合扁平化为一个集合)。