Joins in LINQ

The scenario: you have two related collections of objects, and you need to smush ’em together into a collection of combined records. It’s easy to do with LINQ’s Join method, but Join can seem a little intimidating–just check out its declaration:

// yikes!
public static IEnumerable Join<TOuter, TInner, TKey, TResult>(
	this IEnumerable<TOuter> outer,
	IEnumerable<TInner> inner,
	Func<TOuter, TKey> outerKeySelector,
	Func<TInner, TKey> innerKeySelector,
	Func<TOuter, TInner, TResult> resultSelector
)

It’s really not so bad, though. Here’s the breakdown:

  • “this IEnumerable<TOuter> outer” what you’re joining from
  • “IEnumerable<TInner> inner” what you’re joining to
  • “Func<TOuter, TKey> outerKeySelector” an expression for how to match the ‘from’ records
  • “Func<TInner, TKey> innerKeySelector” an expression for how to match the ‘to’ records
  • “Func<TOuter, TInner, TResult> resultSelector” an expression for the joined result

Still sounds rough? Let’s look at an easy example:

class Person
{
	public string Name;
	public string Occupation;
}

class Job
{
	public string Name;
	public decimal Salary;
}

void Main()
{
	var people = new[]
	{
		new Person { Name = "Adam", Occupation = "Blogger" },
		new Person { Name = "Joe", Occupation = "Teacher" },
		new Person { Name = "Hilary", Occupation = "Actress" }
	};
	var jobs = new[]
	{
		new Job { Name = "Blogger", Salary = 0.0m },
		new Job { Name = "Teacher", Salary = 100.0m },
		new Job { Name = "Actress", Salary = 5000.0m }
	};

	var salaryByPerson = people.Join(
		jobs,
		p => p.Occupation,
		j => j.Name,
		(p,j) => new { Person = p.Name, Salary = j.Salary });

	foreach (var sbp in salaryByPerson)
	{
		Console.WriteLine("Person: {0}, Salary: {1}",
			sbp.Person,
			sbp.Salary.ToString("c"));
	}
}

/* Output
Person: Adam, Salary: $0.00
Person: Joe, Salary: $100.00
Person: Hilary, Salary: $5,000.00
*/

The Join in the above example is equivalent to SQL like this:

SELECT p.Name AS Person, j.Salary
FROM people p
JOIN jobs j ON p.Occupation=j.Name

Now you’ve got it, right? Yea!

Advertisements

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com 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 )

Google+ photo

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

Connecting to %s