How to join two collections with LINQ

How to join two collections with LINQ

Here is a simple and complete example of how to perform joins on two collections with LINQ. I wrote it for a friend to show him, in one simple file, the power of LINQ queries and anonymous objects.
In the file below, there are two simple data classes defined: Person and Item. In the beginning of the main method, two collections are created. Note that the Item's OwnerId field reference the PersonId of a Person object. The effect of the LINQ query below is equivalent to a SQL statement looking like this:

select Person.PersonName as OwnerName, Item.ItemName as OwnedItem from Person inner join Item on Item.OwnerId = Person.PersonId order by Item.ItemName desc;

using System; using System.Collections.Generic; using System.Linq;

namespace LinqJoinAnonymousObjects { class Program { class Person { public int PersonId { get; set; } public string PersonName { get; set; } }

    class Item
    {
        public string ItemName { get; set; }
        public int OwnerId { get; set; }
    }

    static void Main(string\[\] args)
    {
        // Create two collections: one of people, and another with their possessions.
        var people = new List<Person> { 
            new Person { PersonId=1, PersonName="Justin" },
            new Person { PersonId=2, PersonName="Arthur" },
            new Person { PersonId=3, PersonName="Bob" }
        };

        var items = new List<Item> { 
            new Item { OwnerId=1, ItemName="Armor" },
            new Item { OwnerId=1, ItemName="Book" },
            new Item { OwnerId=2, ItemName="Chain Mail" },
            new Item { OwnerId=2, ItemName="Excalibur" },
            new Item { OwnerId=3, ItemName="Bubbles" },
            new Item { OwnerId=3, ItemName="Gold" }
        };

        // Create a new, anonymous composite result for person id=2.
        var compositeResult = from p in people
                               join i in items on p.PersonId equals i.OwnerId
                               where p.PersonId == 2
                               orderby i.ItemName descending
                               select new
                               {
                                   OwnerName = p.PersonName,
                                   OwnedItem = i.ItemName
                               };

        // The query doesn't evaluate until you iterate through the query or convert it to a list
        Console.WriteLine("\[" + compositeResult.GetType().Name + "\]");

        // Convert to a list and loop through it.
        var compositeList = compositeResult.ToList();
        Console.WriteLine("\[" + compositeList.GetType().Name + "\]");
        foreach (var o in compositeList)
        {
            Console.WriteLine("\\t\[" + o.GetType().Name + "\] " + o.OwnerName + " - " + o.OwnedItem);
        }

        Console.ReadKey();
    }
}

}

The output of the program is below:

[WhereSelectEnumerableIterator`2] [List`1] [<>f__AnonymousType1`2] Arthur - Excalibur [<>f__AnonymousType1`2] Arthur - Chain Mail

This article is part of the GWB Archives. Original Author: Justin Greenwood

New on Geeks with Blogs