Pivot Extensions - Download - Source Code

The pivot feature enables transforming a collection of objects into a new collection of objects flattening the original hierarchy.
In the following example The Pivot extension method is used to transform a collection as follow:

pivot1.png

Using the folowing classes:

 public class Contact
  {
    public int Id;

    public string FirstName { get; set; }
    public string LastName { get; set; }
 
    public List<Phone> Phones { get; set; }
   }

 public class Phone
  {
    public Phone(string phoneType, string areaCode, string phoneNumber)
    {
      this.PhoneType = phoneType;
      this.AreaCode = areaCode;
      this.PhoneNumber = phoneNumber;
    }

    public string PhoneType { get; set; }
    public string AreaCode { get; set; }
    public string PhoneNumber { get; set; }
  }

to create the folowing sample data:

 public static class Generator
  {
    public static List<Contact> CreateContacts()
    {
      return new List<Contact>
      {
        new Contact { Id = 1, FirstName = "John"  , LastName = "Doe", Phones = new List<Phone> { new Phone("Home",   "305", "555-1111"),
                                                                                                 new Phone("Office", "305", "555-2222"),
                                                                                                 new Phone("Cell",   "305", "555-3333")} },
        new Contact { Id = 2, FirstName = "Jane"  , LastName = "Doe", Phones = new List<Phone> { new Phone("Home",   "305", "555-1111"),
                                                                                                 new Phone("Office", "305", "555-4444"),
                                                                                                 new Phone("Cell",   "305", "555-5555")} },
        new Contact { Id = 3, FirstName = "Jerome", LastName = "Doe", Phones = new List<Phone> { new Phone("Home",   "305", "555-6666"),
                                                                                                 new Phone("Office", "305", "555-2222"),
                                                                                                 new Phone("Cell",   "305", "555-7777")} },
        new Contact { Id = 4, FirstName = "Joel", LastName = "Smith", Phones = new List<Phone> { new Phone("Fax",    "305", "555-6666"),
                                                                                                 new Phone("Office", "305", "555-2222"),
                                                                                                 new Phone("Cell2",  "305", "555-7778"),
                                                                                                 new Phone("Cell",   "305", "555-7777")}
      } };
    }
  }



In the sample data we have four contacts with a few phone records each. While three contacts have three phones and one contact has four,
there are only five unique phone types: Home, office, Cell, Fax and Cell2.

This is a quick watch view of the contacts before the transformation:

QWOriginal.PNG

Using the following line to pivot the data:
contacts.Pivot(X => X.Phones, X => X.PhoneType, X => string.Concat("(", X.AreaCode, ") ", X.PhoneNumber), true)


We get a new collection as shown in the following:

QWPivot.PNG

The new class ContactWithPivotOnPhone was created on the fly. It inherits from Contact and each instance of ContactWithPivotOnPhone has the original content
from the related contact record. In addition each phone associated with a contact becomes a property in the new type.
The new class also Implements the interface IDynamicPivotObject . This interface enables easy interaction with the new type.

Binding is easy:

Binding without pivoting:

gridView.DataSource = contacts; 
gridView.DataBind(); 

Original.PNG

After pivoting:

gridView.DataSource = contacts.Pivot(X => X.Phones, X => X.PhoneType, X => string.Concat("(", X.AreaCode, ") ", X.PhoneNumber), true).ToArray(); 
gridView.DataBind(); 

Pivot.PNG

Click to see a sample of the C# code generated by the pivot extension.

Last edited Sep 23, 2013 at 7:21 PM by AmirLiberman, version 10

Comments

drdamour Nov 14, 2012 at 11:18 PM 
This is a great function and worked really well. I used it in LINQPad to do a pivot. But note to all, it doesn't seem to work with Anonymous types so be careful! Also, what happens when two instances have the same result from the Key expression?

schandi Jan 19, 2012 at 3:32 PM 
EXCELLENT!!! And EASY to use.. A++

hazzik Oct 30, 2011 at 5:54 AM 
It is awesome!