Visual Studio How-to: LINQ - ' Ordering and grouping' (
Page 3 of 3 )
Ordering, Grouping
This is where things start to get really cool. In traditional database development, grouping and ordering is vital to the creation of nice-looking reports like those created by Crystal Reports. With LINQ you can do both grouping and ordering.
ADVERTISEMENT
Let's try out a collection of all the processes, grouped by physical memory value (say, two groups, those procesess using 50 Meg of memory or more, and those those using under ), and we'll sort each group by process name. (For the physical memory size, we'll use the WorkingSet64 property of the Process instances. Also, note that since 1 Meg is 1024 * 1024 bytes, 50 Meg is 52,428,800 bytes.)
Here's the code:
public static void Linq3()
{
var processes =
from p in Process.GetProcesses()
orderby p.ProcessName
group p by p.WorkingSet64 >= 52428800 into q // 52428800=100*1024^2
select q;
foreach (var x in processes)
{
Console.WriteLine("==================");
foreach (var y in x) {
Console.WriteLine(y.ProcessName + " " + y.WorkingSet64.ToString());
}
}
}
Look at the two additional clauses, orderby and group. (I removed the where clause—which I'm allowed to do—because I want all the elements of the collection.) These must come before the select clause. The orderby clause specifies the ordering; in this case I want the elements ordered by their ProcessName member. The groupby clause uses another lambda expression to determine the groupings.
Here's a partial listing of the results when I ran it on my machine:
The first batch shows those under 50Meg, sorted by name. The second batch shows those over 50 Meg, also sorted by name (although in this case there's only one entry in the second set, dexplore, which is Visual Studio.)
Note that the groupby clause doesn't filter results. My expression p.WorkingSet64 >= 52428800does not mean I'm only going to get back elements where p.WorkingSet64 is greater than or equal to 50 Meg. Instead, I'm using a lambda expression that can return one of two values (true or false), and these two values will be used to build two distinct groups. I could just as easily have used a different lambda expression that can return more than two possible values, such as:
group p by p.WorkingSet64 / 10485760 into q
The expression p.WorkingSet64 / 10485760 returns an integer representing a whole multiple of 10485760 (which is 10 Meg). Thus I'll get a group for those processes between 0 and 10 Meg, those between 10 and 20 Meg, and so on.
In Perspective
Let's step back for a moment and think about what we just did with the process list. Using a very concise syntax, we were able to sort and group a set of data just like we can with an SQL database. But we're not using an SQL database; we're working with a local data collection. And we're using a language much like SQL that is built right into C#. That's pretty powerful!
More to come
There's much more to LINQ than what I'm showing you here. But this will get you started. Some more topics to explore are:
lambda expressions in general and how you can use them in C#
Expression trees you layer up your lambda expressions into an expression tree, which will only be compiled and evaluated after it is needed
DLinq You can use LINQ in conjunction with databases.
I'll blog more about these. And, as I said in my blog, this is definitely an exciting time to be doing Microsoft development! Meanwhile, here's where you can go for more information: