Skip to content

Instantly share code, notes, and snippets.

@bryanhunter
Created May 10, 2012 04:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bryanhunter/2651024 to your computer and use it in GitHub Desktop.
Save bryanhunter/2651024 to your computer and use it in GitHub Desktop.
Simplifies LINQ left joins
using System.Collections.Generic;
namespace System.Linq
{
public static class LeftJoinExtension
{
public static IEnumerable<TResult> LeftJoin<TLeft, TRight, TKey, TResult>(
this IEnumerable<TLeft> left,
IEnumerable<TRight> right,
Func<TLeft, TKey> leftKeySelector,
Func<TRight, TKey> rightKeySelector,
Func<TKey, TLeft, TRight, TResult> resultSelector)
{
return left
.GroupJoin(right,
leftKeySelector,
rightKeySelector,
(l, r) => new {Left = l, Right = r})
.SelectMany(lr => lr.Right.DefaultIfEmpty(),
(l, r) => resultSelector(leftKeySelector(l.Left), l.Left, r));
}
}
}
public void ExtensionTest()
{
// Set up the left-side (always there) data
var people = new List<Person>
{
new Person {Id = 1, Name = "Larry Fine"},
new Person {Id = 2, Name = "Joe Armstrong"},
new Person {Id = 3, Name = "Moe Howard"},
new Person {Id = 4, Name = "Curly Howard"},
new Person {Id = 5, Name = "Bertrand Meyer"},
};
// Set up the right-side (optional) data
var languages = new List<Language>
{
new Language {InventorId = 2, Name = "Erlang"},
new Language {InventorId = 5, Name = "Eiffel"}
};
// Nice and simple...
var result = people.LeftJoin(languages, a => a.Id, b => b.InventorId,
(k, a, b) => new
{
Person = a.Name ,
Language = (b == null) ? "(Stooge)" : b.Name
});
// Kick out the results
foreach (var item in result)
{
Console.WriteLine("{0} - {1}", item.Person, item.Language);
}
}
private class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
private class Language
{
public int InventorId { get; set; }
public string Name { get; set; }
}
Larry Fine - (Stooge)
Joe Armstrong - Erlang
Moe Howard - (Stooge)
Curly Howard - (Stooge)
Bertrand Meyer - Eiffel
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment