I have 2 lists of the same type. The left list:
var leftList = new List();
leftList.Add(new Person {Id = 1, Name = \"John\", Chang
Another way to do it would be:
//Step 1: Merge the lists while selecting the matching objects from rightList using Last()
var mergedList = leftList.Concat(rightList)
.GroupBy(x => x.Id)
.Select(x => x.Last());
//Step 2: Do a inner join between mergedList and leftList to get a left join result as originally required.
var innerJoinQuery = from mPerson in mergedList
join leftPerson in leftList on mPerson.Id equals leftPerson.Id
select new { Id = leftPerson.Id, Name = mPerson.Name, Changed = mPerson.Changed };
This looks like a pretty standard left outer join scenario.
I always keep this extension method handy for left outer joins so I don't have to look up how to use the nasty query syntax (or remember wtf a GroupJoin is)...
public static class LinqEx
{
public static IEnumerable<TResult> LeftOuterJoin<TOuter, TInner, TKey, TResult>(
this IEnumerable<TOuter> outer,
IEnumerable<TInner> inner,
Func<TOuter, TKey> outerKeySelector,
Func<TInner, TKey> innerKeySelector,
Func<TOuter, TInner, TResult> resultSelector)
{
return outer
.GroupJoin(inner, outerKeySelector, innerKeySelector, (a, b) => new
{
a,
b
})
.SelectMany(x => x.b.DefaultIfEmpty(), (x, b) => resultSelector(x.a, b));
}
}
Now you can:
leftList.LeftOuterJoin(
rightList,
lft => lft.Id,
rgt => rgt.Id,
(lft, rgt) => new Person{Id = lft.Id,
Name = lft.Name,
Changed = rgt == null ? lft.Changed : rgt.Changed})
Well spender was faster then me, I did without any extension method.
Without any extension method:
List<Person> mergedList = leftList
.GroupJoin(
rightList, left => left.Id, right => right.Id,
(x, y) => new { Left = x, Rights = y }
)
.SelectMany(
x => x.Rights.DefaultIfEmpty(),
(x, y) => new Person
{
Id = x.Left.Id,
Name = x.Left.Name,
Changed = y == null ? x.Left.Changed : y.Changed
}
).ToList();
The GroupJoin makes left outer join operation.
Why don't you try a solution like this:
var query = (from left in leftList
join right in rightList on left.Id equals right.Id into joinedList
from sub in joinedList.DefaultIfEmpty()
select new Person {
Id = left.Id,
Name = left.Name,
Changed = sub == null ? left.Changed : sub.Changed }).ToList();