score:10

Accepted answer

con isn't in scope in your grouping. Note that in the Microsoft example, their original query element was prod, but after the grouping, they referred to prodGroup.

Your query is grouping the elements together based upon a common Response, you are essentially "losing" the individual con for the greater whole. You may need to expand your grouping to include more criteria than just the Response, such as

group by new { con.Response, con.ActivityID }

and then refer to the ID via

gResponse.Key.ActivityID

Or perhaps access perhaps the first element's ActivityID inside each group

gResponse.First().ActivityID

Without more information as to what you are trying to accomplish, I cannot give specific advice for how you need to proceed.

score:0

Once you've done a group <something> by <function of something> into <group_variable>, your original range variable <something> is no longer available - all the somethings have been grouped up into group_variables, so that's all there is to talk about.

In your example, you start with a load of contributions, but then you group them up - now you have a load of groups, each of which has a Key (the Response used to group them) and a sequence of contributions. If you are happy taking the ActivityID of the first of the contributions in a group (I don't know if this makes sense for you) you could do

select new
{
    grop = gResponse.Count(),
    ActivityID = gResponse.First().ActivityID
}

score:1

You can't access con within your new constructor due to scope. You need to use gResponse to access the data you need.

Think of gResponse as the sum of your parts; make sure that it includes everything you need access to when performing your select new.

score:19

The into clause is a query continuation clause. A query continuation removes all previous range variables from scope and then introduces a new range variable.

That may not be perfectly clear. Let me work up an example that demonstrates it better.

I have brown eyes; my sister has blue eyes. Suppose we wanted to find all the people like me: brown-eyed people with a blue-eyed sibling. We could do it like this:

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;

OK, you've got two queries. The second query operates on the results of the first query. Now, you agree here that "parent" is not in scope inside the second query, right? The "parent" range variable only has meaning within the query that declares it.

You can combine these two queries into one query like this:

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;

Again, it is clear here that "parent" is only in scope in the "inner" query, right?

But this syntax is hard to read compared to the first syntax; why is "parentWithABlueEyedChild" introduced three lines before it is used? The first version was more clear. We can make this into one query while maintaining the readability of the first version with a query continuation:

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;

That's exactly the same as the first two versions. The continuation is just a convenience. parent is not in scope in the continuation clause, because it would not be in scope if you wrote them out as two queries.

Is it now clear why "con" is not in scope in your continuation? Your query

var q = 
    from con in contributions
    group con by con.Response
    into gResponse
    select new 
    {
        grop = gResponse.Count(),
        con.ActivityID
    }; 

is exactly the same as

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" is not in scope inside the second query; it is only part of the first query.


Related Query

More Query from same tag