Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用linq指定子查询的子查询的正确方法_C#_Linq_Entity Framework - Fatal编程技术网

C# 使用linq指定子查询的子查询的正确方法

C# 使用linq指定子查询的子查询的正确方法,c#,linq,entity-framework,C#,Linq,Entity Framework,我想我错过了这里的连接。但也许它们是暗示的?执行时间太长,我无法观察以计算生成的查询表达式此查询中最大的问题是: 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);
你明白为什么这会很糟糕吗?对于每个结果,都运行一个子查询,而子查询本身就是在运行一个子查询。由于这些嵌套的子查询,当您开始在根级别、结果和建筑物添加内容时,时间/处理将呈指数级增长。最好的办法是使用联接,并在完成后获得不同的r值。SQL希望如下所示:

--@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))
这将起作用的原因是,当您加入时,如果有多个要重新加入,它将复制原始行。下图显示了

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
假设S=2和S=6满足您的条件,那么它将以R、X、S的形式返回第1、1、2和1、2、6行。在本例中,仅获取不同的r只会返回r=1,这是您试图实现的。使用EF,这些关系已经存在,因此您不需要做任何额外的事情,只需引用您试图筛选的列:

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

这是SelectMany操作符,它使用一个集合并将子集合展平到单个集合中

results=来自results中的r,呃,向我们展示之前查询的部分。您似乎已经理解了我的问题。我以为EF会处理很多繁重的工作。让我测试一下,然后再给你回复。没问题。如果关系设置不正确,那么SelectMany最终将来自查询世界中的TableA、TableB。这就是为什么EF和L2S为您处理关系,并将这些引用转换为联接。一般来说,我会说,即使在SQL世界中处理嵌套关系时,也要尽量远离任何嵌套关系。我不知道自己在做什么\好的,这很有效。如果我将表达式查询复制到T-SQL中,它将返回预期的行数,但在应用程序中,它每次返回0行。我想我必须提出另一个问题。在再次开始对结果进行查询之前,确保结果中确实包含数据。更有可能的是,这就是正在发生的事情。如果您想要新的数据,那么只需确保执行context.Set即可获取对结果实体的引用。
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();