Grouping Operator Examples

In this example I’ll be demonstrating a few ways to use the GroupBy and ToLookup LINQ keywords in some queries. I’ve divided this up between three methods. One method showing a basic GroupBy example. The second method showing examples on some in-memory data. And the third example on some database data.

MoreGroupingSolution MoreGroupingProgram

 

WriteResults.cs Code Contents

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MyLinq
{
    public static class WriteResults
    {
        // Public Static Methods
        //
        public static void WriteDeptAndEmployee(ILookup<string, string> query)
        {
            foreach (var departmentName in query)
            {
                Console.WriteLine("Department: {0}", departmentName.Key);
                foreach (var employees in departmentName)
                {
                    Console.WriteLine("Employee: {0}", employees);
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }

        public static void WriteMovieAndReleaseDate(IQueryable<MovieAndReleaseDate> query)
        {
            foreach (var movieInfo in query)
            {
                Console.WriteLine("Year Released: {0}", movieInfo.ReleaseDate);
                Console.WriteLine("Movie Name: {0}", movieInfo.Title);
                Console.WriteLine();
            }
        }
    }
}

As you can see I’ve taken out some code from the last example only concentrating on the write methods that I’ll need in this example.

 
Program.cs Code Contents

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Xml.Linq;
using System.Diagnostics;
using System.Collections;

namespace MyLinq
{
    class Program
    {
        /// <summary>
        /// Demonstrating examples of different ways to use GroupBy and ToLookup methods.
        /// </summary>
        /// <param name="args"></param>

        static void Main(string[] args)
        {
            executeSimpleGroupingExample();
            executeInMemoryGrouping();
            executeDatabaseGrouping();

            Console.ReadLine();
        }

        //Private Methods
        //
        private static void executeSimpleGroupingExample()
        {
            int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            var query = numbers.GroupBy(i => i % 2);
            foreach (var group in query)
            {
                Console.WriteLine("Key: {0}", group.Key);
                foreach (var number in group)
                {
                    Console.WriteLine(number);
                }
            }
            Console.WriteLine();
        }

        private static void executeInMemoryGrouping()
        {
            var employeeRepo = new EmployeeRepo();
            var departmentRepo = new DepartmentRepo();

            // Executing the group operator on some in memory objects.
            // Note that the group operator is a lazy operator meaning the execution is deferred.
            var inMemoryBasicGroupQuery = from e in employeeRepo.GetAll()
                                          group e by e.DepartmentID;

            var inMemorySelectQuery = from e in employeeRepo.GetAll()
                                      group e by e.DepartmentID into eg
                                      select new { DepartmentID = eg.Key, Employees = eg };

            // The GroupBy operator will defer the query until it's ran.
            var inMemoryExtensionQuery = employeeRepo.GetAll().GroupBy(employeeDeptID => employeeDeptID.DepartmentID, employeeName => employeeName.Name)
                                                              .Select(eg => new { DepartmentID = eg.Key, Employees = eg });

            // If using the ToLookup operator it's a greedy operator meaning the execution is immediate.
            var inMemoryExtensionToLookupQuery = employeeRepo.GetAll().ToLookup(e => e.DepartmentID)
                                                              .Select(eg => new { DepartmentID = eg.Key, Employees = eg });

            // Using the actions of the Join operator, running the Distinct operator on that query to remove any duplicate data then running the
            // GroupBy operator in one query.
            var combinedGroupByQuery = departmentRepo.GetAll().Join(employeeRepo.GetAll(), d => d.ID, e => e.DepartmentID,
                                                                   (d, e) => new EmployeeAndDepartment(e.Name, d.Name)).Distinct()
                                                                   .GroupBy(employeeDept => employeeDept.EmployeeDepartment, employeeName => employeeName.EmployeeName);

            // Using the actions of the Join operator, running the Distinct operator on that query to remove any duplicate data then running the
            // ToLookup operator in one query.
            var combinedToLookupQuery = departmentRepo.GetAll().Join(employeeRepo.GetAll(), d => d.ID, e => e.DepartmentID,
                                                                   (d, e) => new EmployeeAndDepartment(e.Name, d.Name)).Distinct()
                                                                   .ToLookup(employeeDept => employeeDept.EmployeeDepartment, employeeName => employeeName.EmployeeName);

            // Displaying Results
            //
            // Displaying the results from the query with an anonymous type.
            Console.WriteLine("****Displaying The GroupBy Query Results****");
            foreach (var deptID in inMemoryExtensionQuery)
            {
                Console.WriteLine("Department ID: {0}", deptID.DepartmentID);
                foreach (var employees in deptID.Employees)
                {
                    Console.WriteLine("Employee Name: {0}", employees);
                }
                Console.WriteLine();
            }

            // Displaying the results from the query with a strongly typed object.
            Console.WriteLine("****Displaying The Distinct ToLookup Query Results****");
            WriteResults.WriteDeptAndEmployee(combinedToLookupQuery);
        }

        public static void executeDatabaseGrouping()
        {
            MovieReviewsDataContext movieReviewsContext = new MovieReviewsDataContext();

            // Running GroupBy and ToLookup queries in both comprehension and extension method syntax examples on the 
            // movie database.
            var databaseGroupQuery = from m in movieReviewsContext.Movies
                                     group m by m.MovieID into mg
                                     select new { MovieID = mg.Key, Movies = mg };

            // GroupBy query on the movie database by their release date.
            var databaseExtensionQuery = movieReviewsContext.Movies.GroupBy(m => m.ReleaseDate)
                                                            .Select(mg => new { MovieID = mg.Key, Movies = mg });

            // ToLookup query on the movie database by their release date.
            var databaseExtensionLookupQuery = movieReviewsContext.Movies.ToLookup(m => m.ReleaseDate)
                                                                    .Select(mg => new { MovieID = mg.Key, Movies = mg });

            // GroupBy query on the movie database with a strongly types object.
            var strongTypedObjectDatabaseQuery = movieReviewsContext.Movies.GroupBy(mt => new { mt.ReleaseDate, mt.Title },
                                                                                   (key, group) => new MovieAndReleaseDate(key.ReleaseDate, key.Title));

            // Displaying Results
            //
            // Displaying the results from the query with an anonymous type.
            Console.WriteLine("****Displaying The Movie GroupBy Results****");
            foreach (var movieReleasedYear in databaseExtensionQuery)
            {
                Console.WriteLine("Year: {0}", movieReleasedYear.MovieID);
                foreach (var movie in movieReleasedYear.Movies)
                {
                    Console.WriteLine("Movie: {0}", movie.Title);
                }
                Console.WriteLine();
            }

            // Displaying the results from the query with a strongly typed object.
            Console.WriteLine("****Displaying The Strongly Typed Object Movie Results****");
            WriteResults.WriteMovieAndReleaseDate(strongTypedObjectDatabaseQuery);
        }
    }
}

The first executeSimpleGroupingExample method is taking an array of integers and creating a query that does a GroupBy on all the numbers that divisible by 2. Then I’m using nested foreach loops to get the Key and display the numbers in those Keys.

The second executeInMemoryGrouping method is doing multiple queries using GroupBy and the ToLookup operators. I’m showing the difference between the two by showing that the GroupBy query is a lazy operator and the ToLookup operator is a greedy operator. Meaning that the GroupBy operator operation is deferred and the ToLookup operator isn’t deferred. You will also notice that I’m creating both anonymous types and strongly types objects in my queries here.

The third executeDatabaseGrouping method is doing GroupBy and ToLookup on the movie database. There are three queries that are doing various examples of these operators. One is doing a GrouBy on the movie release data and creating an anonymous type. Another query is performing a ToLookup on the movie release date, selecting it, and creating an anonymous type. The third query is performing a GroupBy on the release data and movie title and creating a strongly types object from the data.

The write results of both main methods are doing a combination of iterating thru the queries with anonymous types and making use of the WriteResults static class methods. Again this is to show multiple ways to do this. Personal preferences aside.. 🙂

Advertisements

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s