【问题标题】:Having some trouble understanding Linq's INTO keyword无法理解 Linq 的 INTO 关键字
【发布时间】:2023-04-01 11:50:01
【问题描述】:

1)

into 关键字创建用于存储连接结果的临时标识符, 分组或选择子句。

我假设 into 关键字只能用作 groupjoin 或 select 子句的一部分?

2)

a) 我读到,当into 用作 groupselect 子句的一部分时,它将查询分成两半,因此在查询的前半部分声明的范围变量总是在查询的后半部分超出范围。对吗?

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

c) 查询表达式由 from 子句和可选的查询主体(from,where,let 子句)组成,并且必须以 select 或 group 子句。

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

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

谢谢


回复 Ufuk:

一)

在 group by 之后,您会得到这样的序列 IEnumerable>

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

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

回复 Robotsushi:

我想的越多,我就越觉得我的问题毫无意义,因为它没有任何实际价值。还是……

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

这是引用:

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

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


2。回复机器人寿司:

您的这部分查询被评估为一个数据拉取。

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

【问题讨论】:

  • 关于你最后一个问题,什么是“身体”?
  • Book 将查询分为三部分(from 子句、body(let/from/orderby/where 子句所在的位置)和 final 子句,可以是组或 select 子句)。
  • 当你说它被分裂时。你的意思是变量的范围被拆分还是生成的sql查询被拆分?
  • 您对按返回类型分组是正确的。我只是想让您了解项目现在处于嵌套序列中,因此它们超出了范围。我已经更新了我的答案。

标签: c# linq


【解决方案1】:

分组...按...进入

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

你有一个这样的序列:

IEnumerable<Foo>

在分组后你会得到一个这样的序列

IEnumerable<Key,IEnumerable<Foo>>

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

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

join ... on ... into

另一方面,group join 不是那种操作。它们对两个序列进行操作,而 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.

【讨论】:

    【解决方案2】:

    1) 正确...更具体地,为超出范围的连接、组或选择子句的结果提供引用

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

    只有在你想要的时候才需要在 group 子句中使用 into 对每个组执行额外的查询操作

    添加响应

    我已经读到,当 into 用作 group 或 select 的一部分时 子句,它将查询拼接成两半,并且由于该范围 在查询的前半部分声明的变量总是超出范围 在查询的后半部分。对吗?

    您的这部分查询被评估为一个数据拉取。 group 关键字需要排序操作才能继续评估您的 LINQ 查询:

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

    所以在下面的选择中:

    选择...

    查询第一部分的变量将被评估,但是由于您包含 into 关键字,您可以在选择中使用查询结果,因为它们存储在 GroupResult变量。

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

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

    查询表达式由 from 子句后跟可选 查询主体(from、where、let 子句)并且必须以 select 结尾 组子句。

    这是一个定义而不是一个问题。

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

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

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

    第二次更新

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

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

    【讨论】:

    • 你能看到我的第二次编辑吗(我将把它作为我的最后一个回复)?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-17
    • 1970-01-01
    • 1970-01-01
    • 2019-01-05
    • 1970-01-01
    相关资源
    最近更新 更多