我正在尝试使用LINQ创建一个group by语句。我收到错误当前上下文中不存在名称'con'。
在我选择的代码后,我尝试获取ActivityID
值,但列表'con'不可用。
List<Contribution> contributions =
contLogic.GetAllContibutionsByActivityIDToList(ActivityID);
var groups = from con in contributions
group con by con.Response
into gResponse
select new
{
grop = gResponse.Count(),
con.ActivityID
};
我看过微软的样本,我不知道我做错了什么。
Microsoft示例:
List<Product> products = GetProductList();
var orderGroups = from prod in products
group prod by prod.Category into prodGroup
select new { Category = prodGroup.Key, Products = prodGroup };
ObjectDumper.Write(orderGroups, 1);
答案 0 :(得分:19)
into
子句是查询延续子句。查询延续从范围中删除所有先前的范围变量,然后引入新的范围变量。
这可能不太清楚。让我举一个更好地展示它的例子。
我有棕色的眼睛;我的妹妹有蓝色的眼睛。假设我们想找到像我这样的所有人:棕眼睛的人,有着蓝眼睛的兄弟姐妹。我们可以这样做:var parentsWithABlueEyedChild =
from parent in parents
where parent.Children.Any(c=>c.EyeColor == Blue)
select parent;
var brownEyedChildren =
from parentWithABlueEyedChild in parentsWithABlueEyedChild
from child in parentWithABlueEyedChild.Children
where child.EyeColor == Brown
select child;
好的,你有两个问题。第二个查询对第一个查询的结果进行操作。现在,您同意“父”不在第二个查询的范围内,对吧? “父”范围变量仅在声明它的查询中具有含义。
您可以将这两个查询合并为一个查询,如下所示:
var brownEyedChildren =
from parentWithABlueEyedChild in (
from parent in parents
where parent.Children.Any(c=>c.EyeColor == Blue)
select parent)
from child in parentWithABlueEyedChild.Children
where child.EyeColor == Brown
select child;
同样,这里很明显“父”只在“内部”查询的范围内,对吗?
但与第一种语法相比,这种语法难以阅读;为什么“parentWithABlueEyedChild”在使用之前引入了三行?第一个版本更清晰。我们可以将它组合成一个查询,同时通过查询延续来保持第一个版本的可读性:
var brownEyedChildren =
from parent in parents
where parent.Children.Any(c=>c.EyeColor == Blue)
select parent into parentWithABlueEyedChild
from child in parentWithABlueEyedChild.Children
where child.EyeColor == Brown
select child;
与前两个版本完全相同。延续只是一种便利。 parent
不在continuation子句的范围内,因为如果将它们写成两个查询,它就不在范围内。
现在清楚为什么“con”不在你的延续范围内?您的查询
var q =
from con in contributions
group con by con.Response
into gResponse
select new
{
grop = gResponse.Count(),
con.ActivityID
};
与
完全相同var gResponses =
from con in contributions
group con by con.Response;
var q =
from gResponse in gResponses
select new
{
grop = gResponse.Count(),
con.ActivityID
};
“con”不在第二个查询的范围内;它只是第一个查询的一部分。
答案 1 :(得分:10)
con
不在您的分组范围内。请注意,在Microsoft示例中,其原始查询元素为prod
,但在分组后,它们引用了prodGroup
。
您的查询是根据共同的Response
将元素分组在一起,您实际上是“失去”个人con
以获得更大的整体。您可能需要扩展分组以包含比响应更多的条件,例如
group by new { con.Response, con.ActivityID }
然后通过
引用IDgResponse.Key.ActivityID
或者也许可以在每个组中访问第一个元素的ActivityID
gResponse.First().ActivityID
如果没有关于您要完成什么的更多信息,我无法就您需要如何继续提供具体建议。
答案 2 :(得分:1)
由于范围原因,您无法在新构造函数中访问con
。您需要使用gResponse
来访问所需的数据。
将gResponse
视为各部分的总和;确保在执行select new
时包含您需要访问的所有内容。
答案 3 :(得分:0)
完成group <something> by <function of something> into <group_variable>
后,原始范围变量<something>
不再可用 - 所有something
已被分组到group_variable
s,所以这就是我们要讨论的内容。
在您的示例中,您从一大堆贡献开始,然后将它们分组 - 现在您有一大堆组,每个组都有一个Key
({ {1}}用于对它们进行分组)和一系列贡献。如果您乐意接受小组中第一个贡献的Response
(我不知道这对您是否有意义),您可以这样做
ActivityID