在理解Linq的INTO关键字时遇到一些麻烦

时间:2011-09-11 17:55:13

标签: c# linq

1)

  

into keyword创建用于存储join的结果的临时标识符,   分组或选择条款。

我认为into关键字只能用作 join 或select子句的一部分?

2)

a)我读过当into用作选择子句的一部分时,它会将查询拼接成两半并因为在查询的前半部分声明的范围变量ALWAYS超出了查询后半部分的范围。正确的吗?

b)但是当into用作 join 子句的一部分时,rangle变量永远不会超出查询范围(除非查询还包含group...intoselect...into)。我假设这是因为into在与 join 子句一起使用时没有将查询拼接成两半?

c)中 查询表达式由 from 子句后跟可选查询体( from,where,let 子句)组成,并且必须以 select < em> group 子句。

d)如果into确实将查询拼接成两半,则在以下示例中 group 子句是正文的一部分:

        var result = from c1 in a1
                     group c1 by c1.name into GroupResult
                     select ...

谢谢


回复Ufuk:

A)

  

经过一组你得到一个这样的序列   IEnumerable的&GT;

GroupBy运算符不会返回IEnumerable<IGrouping<Key,Foo>>类型的结果,而不是IEnumerable<Key,IEnumerable<Foo>>

b)我们不能认为group...by...intojoin...into在查询的前半部分至少在概念上必须在查询的后半部分可以运行之前运行的情况下拼接查询吗?

回复Robotsushi:

我越是想到它,我越觉得我的问题毫无意义,因为它没有任何实际价值。仍然...

  

当你说它被拆分时。你的意思是变量的范围   被拆分或生成的sql查询被拆分

这是引用:

  

在许多情况下,这种鸿沟的一侧的范围变量不可能   与另一侧的范围变量混合。关键字   这是group-by子句的一部分,用于链接或拼接   这个查询的两半。因此,它标志着中间的边界   查询范围变量通常无法攀升的问题。该   into关键字上方的范围变量超出了范围   这个查询的一部分。

我的问题是两个半部是否仍被视为单个查询,因此整个查询仍然只包含三个部分。如果是这种情况,那么在我的代码示例中(在d)下)group子句是正文的一部分。但如果两半都被认为是两个查询,则两个查询中的每一个都将由三部分组成


2。回复Robotsushi:

  

您的查询块被评估为一次数据提取。

我不熟悉术语“数据拉动”,所以我猜你要说的是查询的前半部分作为一个单元执行/评估,然后是后半部分查询从前半部分获取结果并在执行/评估中使用结果?换句话说,从概念上讲,我们有两个问题?

2 个答案:

答案 0 :(得分:3)

分组......由...进入

操作后group by必须提供不同类型的序列。

你有这样的序列:

IEnumerable<Foo>

经过一组你得到一个像这样的序列

IEnumerable<Key,IEnumerable<Foo>>

现在您的商品是嵌套序列,您无法直接访问它们。这就是为什么第一部分中的标识符超出范围的原因。由于您的第一部分超出了范围,因此您将在进入之后留下标识符。它已经结束,可以开始新的查询。查询的第二部分与第一部分完全不同。这是一个延续。

from foo in foolist
group foo by foo.name into grouped
//foo is out of scope, you are working on a different sequence now
//and you have a ready to use range variable for your second query

加入......进入

另一方面,组连接不是那种操作。它们在两个序列上运行,其中group by在一个上运行。它们将在左序列的正确序列上提供匹配元素。

IEnumerable<Left> and IEnumerable<Right>

操作后,它允许您使用左侧序列中的标识符,但右侧的标识符超出范围。那是因为join现在返回它们的序列。所以你再也没有直接访问它们了。小组加入的结果如下:

IEnumerable<Left,IEnumerable<Right>>

使用组连接时,只有右范围变量超出范围。虽然左侧部分仍然存在,但您仍在使用相同的序列。您尚未提供投影,因此无法继续第二次查询。

from left in leftList
join right from rightList
    on left.Key equals right.Key into joinedRights
// left is still your range variable, you are still enumerating leftList
// you have to provide a projection here but you won't have a ready to use range variable
// that's why it's not a continuation.

答案 1 :(得分:1)

1)更正...更具体地提供引用到将超出范围的join,group或select子句的结果。

2)我不认为您的查询因使用而被拆分,因为它最常用的是:

  

只有在您需要时才需要在组子句中使用   对每个组执行其他查询操作

已添加回复

  

我已经读过,当into用作组的一部分或选择时   条款,它将查询拼接成两半并且因为该范围   在查询的前半部分声明的变量总是超出范围   在查询的后半部分。正确的吗?

您的查询块被评估为一次数据提取。 group关键字需要排序操作才能继续评估LINQ查询:

from c1 in a1
group c1 by c1.name into GroupResult

所以在下面选择:

  

选择......

我们已经评估了查询第一部分中的变量,但是由于您包含了关键字,因此可以在select中使用查询结果,因为它们存储在GroupResult中变量

  

但是当into用作join子句的一部分时,rangle变量   永远不要超出查询范围(除非查询也是如此)   包含group ... into或select ... into)。我认为这是由于进入   与join子句一起使用时,不将查询拼接成两半?

查询仍然分为两部分进行评估,但GroupResult可让您访问关键字之前声明的内容。

  

查询表达式由from子句后跟可选项组成   查询主体(from,where,let子句),必须以select结尾   小组条款。

这个定义不是问题。

  

如果确实将拼接查询分为两半,则在下面   示例组子句部分:

该组是查询前半部分的一部分。

显示的这个LINQ查询会生成一个sql语句,以防你好奇。

第二次更新

  

我不熟悉“数据拉动”一词,所以我猜这个   你想说的是查询的前半部分   执行/评估为一个单元,然后查询的后半部分   上半年的结果并将结果用于其中   执行/评估?换句话说,从概念上讲,我们有两个   疑问?

是的,查询有两个不同的部分。