ENTERPRISE

LINQ to Objects : How to Group Elements (part 3) - Grouping by Composite Keys

12/30/2013 8:45:04 PM

3. Grouping by Composite Keys (More Than One Value)

To group using more than one value as the key (often referred to as a composite key), you specify the grouping selector clause as an anonymous type. Any number of key values can be specified in this anonymous type, and any element that contains identical values will dutifully be co-located in a group.

Listing 3 demonstrates the simplicity of specifying multiple key values in the group by expression. In this case, the LastName and the State fields are used for grouping, placing all contacts with the same last name from the same state in a group. The Console output from this example is shown in Output 2.

Listing 3. Anonymous types can be used to group by more than one value (composite key)—see Output 2
/* this sample uses the same data as we saw in Table 2-2,
but i've added 2 Gottshall's (one from the same state
and another out of that state), and 2 Gauwain's -

Firstname Lastname State
-----------------------------
Barney Gottshall CA
Mandy Gottshall CA *added
Bernadette Gottshall WA *added
Armando Valdes WA
Adam Gauwain AK
Chris Gauwain AK *added
Anthony Gauwain CA *added
Jeffery Deane CA
Collin Zeeman FL
Stewart Kagel WA
Chance Lard WA
Blaine Reifsteck TX
Mack Kamph TX
Ariel Hazelgrove OR
*/

var q = from c in Contact.SampleData()
group c by new { c.LastName, c.State };

foreach (var grp in q)
{
Console.WriteLine("Group - {0}, {1} - count = {2}",
grp.Key.LastName,
grp.Key.State,
grp.Count());
}


Output 2.
Group - Gottshall, CA - count = 2
Group - Gottshall, WA - count = 1
Group - Valdes, WA - count = 1
Group - Gauwain, AK - count = 2
Group - Gauwain, CA - count = 1
Group - Deane, CA - count = 1
Group - Zeeman, FL - count = 1
Group - Kagel, WA - count = 1
Group - Lard, WA - count = 1
Group - Reifsteck, TX - count = 1
Group - Kamph, TX - count = 1
Group - Hazelgrove, OR - count = 1

It is not essential to use an anonymous type as the grouping key selector to achieve multiple-property groups. A named type containing all of the properties participating in the key can be used for the same purpose, although the method is more complex because the type being constructed in the projection needs a custom override of the methods GetHashCode and Equals to force comparison by property values rather than reference equality. Listing 4 demonstrates the mechanics of creating a class that supports composite keys using the fields LastName and State. The results are identical to that shown in Output 2.


Listing 4. Creating a composite join key using a normal class type
public class LastNameState
{
public string LastName { get; set; }
public string State { get; set; }

// follow the MSDN guidelines -
// http://msdn.microsoft.com/en-us/library/
// ms173147(VS.80).aspx
public override bool Equals(object obj)
{
if (this != obj)
{
LastNameState item = obj as LastNameState;
if (item == null) return false;
if (State != item.State) return false;
if (LastName != item.LastName) return false;
}

return true;
}

// follow the MSDN guidelines -
// http://msdn.microsoft.com/en-us/library/
// system.object.gethashcode.aspx
public override int GetHashCode()
{
int result = State != null ? State.GetHashCode() : 1;
result = result ^
(LastName != null ? LastName.GetHashCode() : 2);

return result;
}
}

var q = from c in Contact.SampleData()
group c by new LastNameState {
LastName = c.LastName, State = c.State };


Other  
  •  Moving into SAP Functional Development : Gaining Control of Change Control - Change Management Best Practices and Approaches (part 4)
  •  Moving into SAP Functional Development : Gaining Control of Change Control - Change Management Best Practices and Approaches (part 3)
  •  Moving into SAP Functional Development : Gaining Control of Change Control - Change Management Best Practices and Approaches (part 2)
  •  Moving into SAP Functional Development : Gaining Control of Change Control - Change Management Best Practices and Approaches (part 1)
  •  Moving into SAP Functional Development : Gaining Control of Change Control - An Overview of Change Management
  •  Performing mySAP.com Component Installations : Addressing General mySAP Post-Installation Tasks
  •  Programming .NET Components : Working with Threads (part 5) - Thread States, Thread Priority and Scheduling
  •  Programming .NET Components : Working with Threads (part 4) - Aborting a Thread
  •  Programming .NET Components : Working with Threads (part 3) - Blocking Threads
  •  Programming .NET Components : Working with Threads (part 2) - Creating Threads
  •  
    Top 10
    Review : Sigma 24mm f/1.4 DG HSM Art
    Review : Canon EF11-24mm f/4L USM
    Review : Creative Sound Blaster Roar 2
    Review : Philips Fidelio M2L
    Review : Alienware 17 - Dell's Alienware laptops
    Review Smartwatch : Wellograph
    Review : Xiaomi Redmi 2
    Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
    Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
    3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
    REVIEW
    - First look: Apple Watch

    - 3 Tips for Maintaining Your Cell Phone Battery (part 1)

    - 3 Tips for Maintaining Your Cell Phone Battery (part 2)
    VIDEO TUTORIAL
    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
    Popular Tags
    Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8