当前上下文中不存在名称“con”

时间:2011-12-21 16:09:27

标签: c# linq

我正在尝试使用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);

4 个答案:

答案 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 }

然后通过

引用ID
gResponse.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