I have 2 lists and I need to combine the joining values from A and B, but also include the values from A and B that don't match the join.
class TypeA
{
public string Key { get; set; }
public int ValueA { get; set; }
}
class TypeB
{
public string Key { get; set; }
public int ValueB { get; set; }
}
class TypeAB
{
public string Key { get; set; }
public int ValueA { get; set; }
public int ValueB { get; set; }
}
var listA = new List<TypeA>
{
new TypeA { Key = "one", Value = 1 },
new TypeA { Key = "two", Value = 2 },
};
var listB = new List<TypeB>
{
new TypeB { Key = "two", Value = 2 },
new TypeB { Key = "three", Value = 3 },
};
I want these lists combined to equal this:
var listAB = new List<TypeAB>
{
new TypeAB { Key = "one", ValueA = 1, ValueB = null },
new TypeAB { Key = "two", ValueA = 2, ValueB = 2 },
new TypeAB { Key = "three", ValueA = null, ValueB = 3 },
};
What is a Linq statement that will do this? I've been playing around and can't quite get there. I can get almost there by doing a left outer join on A to B and Union that to a left outer join on B to A, but I get duplicate Intersection values.
Update
Here is what I did based on George's answer:
var joined =
( from a in listA
join b in listB
on a.Key equals b.Key
into listBJoin
from b in listBJoin.DefaultIfEmpty( new TypeB() )
select new TypeAB
{
Key = a.Key,
ValueA = a.ValueA,
ValueB = b.ValueB,
} ).Union(
from b in listB
where !listA.Any( d => d.Key == b.Key )
select new TypeAB
{
Key = b.Key,
ValueB = b.ValueB,
}
).ToList();