My goal is to group and transform data, but have both the transformed and un-transformed "grouped data" available.
Consider the following minimal C# example:
var data = new[] { ("a", 1), ("a", 2), ("b", 1) };
var groupedAndTransformed =
from d in data
group d by d.Item1 into g
select new
{
Untransformed = g,
Transformed = g.Key + string.Join(",", g.Select(tuple => tuple.Item2))
};
Now I try to do the same in VB.NET, but I can only achieve that with a two-step process, because VB.NET's Group By works somewhat differently than C#'s group by:
Dim data = {("a", 1), ("a", 2), ("b", 1)}
Dim step1 =
From d In data
Group d By d.Item1 Into Group
Dim groupedAndTransformed =
From g In step1
Select
Untransformed = g,
Transformed = g.Item1 + String.Join(",", g.Group.Select(Function(tuple) tuple.Item2))
The problem seems to be that VB.NET's Group By puts the result of the grouping into some kind of "global namespace": If I continue writing LINQ code directly after Group d By d.Item1 Into Group, I have both Item1 and Group in scope. However, I don't have a name for the IGrouping consisting of them (dubbed g in C#), so I need the second step.
Can I somehow tell VB's Group By statement to give me a name for the IGrouping? The only other workarounds I found were to use (a) functional syntax instead of declarative LINQ syntax (i.e., call Enumerable.GroupBy directly) or (b) nest step1 into the second step (i.e., From g In (...step1...)). Is there something I have missed?