c# - 为什么我的 linq 别名超出范围?

标签 c# linq

我正在尝试更好地理解更复杂的 linq 语句。多亏了网络上的几篇文章,我才有所了解。我不明白的一件事是为什么我的查询别名在此语句中脱离上下文:

(from query in _context.WebQueries
            select query).Where((from qry in _context.WebQueries
                join qg in _context.WebQueryGroups on qry.QueryKey equals qg.QueryKey
                where qg.QueryGroupNameKey == key
                                              //This is out of scope
                select qry.QueryKey).Contains(query.QueryKey));
                                    //if you replaced it with this same problem
                                    .Contains(qry.QueryKey));

我知道我可以使用匿名对象调用并获得我想要的结果。我只需要迭代对象并拉出我想要的列表:

(from query in _context.WebQueries
         select new {query, key = query.QueryKey})
         .Where(q => !(from qry in _context.WebQueries
                join qg in _context.WebQueryGroups on qry.QueryKey equals qg.QueryKey
                where qg.QueryGroupNameKey == key
                select qry.QueryKey).Contains(q.key));

这会返回一个对象,其中包含我想要的列表和我想稍后在查询中引用的 int。

为什么 query 和 qry 都超出了范围?我宁愿只在我的方法中返回 linq 语句,而不必解析对象来获取要返回的列表。讨论这个问题的文章会很棒。

最佳答案

我注意到您没有得到您具体问题的答案,据我了解,这是“查询中的范围规则是什么?”

首先,让我们仔细定义“范围”。实体的范围是程序文本的一个区域,其中可以通过非限定名称引用特定实体。

了解范围变量作用域的关键是了解编译器如何翻译查询。这是一个句法翻译。当你说:

from r in s where t select u

编译器在句法上将其翻译成:

((s).Where(r => t)).Select(r => u)

在翻译版本中有两个 r,都是 lambda 形式参数,并且适用 lambda 的常规范围规则;每个仅在 lambda 主体的范围内。

现在您知道为什么不能在查询之外使用范围变量了;该范围变量实际上是一个或多个 lambda 的形式参数,因此仅在这些 lambda 的主体中有效。

您可以通过阅读有关查询翻译的 C# 规范部分来了解其余规则。我注意到“透明标识符”查询的规则具有棘手的范围界定,因此请仔细阅读该部分。我一直想就此写一篇博客文章。

更新:我开始写那篇博文;你可以在这里阅读:

http://ericlippert.com/2014/07/31/transparent-identifiers-part-one/

http://ericlippert.com/2014/08/01/transparent-identifiers-part-two/

关于c# - 为什么我的 linq 别名超出范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24995477/

相关文章:

c# - 如何在 linq to NHibernate 中使用 select for associations

c# - 将 ParameterExpression 解析为实际表达式

c# - OPC dll - 如何批量检索标签值

c# - 优化自然排序序列的 Join、GroupBy、Distinct、Min/Max

c# - 在客户端打印而不显示打印对话框

c# - 用 linq 替换两个 foreach 循环

linq - 帮助linq查询

c# - 为什么在 WPF 中将 INotifyPropertyChanged 与绑定(bind)一起使用?

c# - 从包含特定子字符串的列表中删除所有字符串

c# - 通过 Linq 比较两个数据表