I have two DataTables t1 and t2. I’m trying to perform a LINQ left join, multiple equijoin, to get the DataRows in t1 that are not in t2.
In SQL, what I’m trying to accomplish is:
select t1.*
from t1
left join t2
on t1.a=t2.a and
t1.b=t2.b and
t1.c=t2.c
where
t2.a is null
So far I have the following:
public DataTable t1_without_t2(DataTable t1, DataTable t2)
{
var query = from t1_row in t1.AsEnumerable()
join t2_row in t2.AsEnumerable()
on
new { t_a = t1_row["a"], t_b = t1_row["b"], t_c = t1_row["c"]}
equals
new { t_a = t2_row["a"], t_b = t2_row["b"], t_c = t2_row["c"]}
into leftJoinT1withoutT2
from join_row in leftJoinT1withoutT2.DefaultIfEmpty()
where t2_row["a"] == null
select new
{
j_a = join_row["a"],
j_b = join_row["b"],
j_c = join_row["c"],
};
DataTable dt = t1.Clone();
foreach (var result in query)
{
dt.LoadDataRow(
new object[]
{
result.j_a,
result.j_b,
result.j_c
},
false);
}
return dt;
}
This is failing on the line j_a = join_row["a"] with this message:
Column 'a' does not belong to table.
I thought that the into leftJoinT1withoutT2 line was supposed to put the results of the join into a var with the column structure of table t1, from which the non-matching entries would be removed using where t2_row["a"] == null . Is that not what’s happening here? I’m a little confused.
It should look like this:
Have a look at How to: Perform Left Outer Joins (C# Programming Guide).
The
join_rowgetsnull(i.e. defaultTSourcevalue, see Enumerable.DefaultIfEmpty) when there is no matching element int2, whilet1_rowalways contains the joined value. So as far as you need only those rows for whichjoin_rowisnull, I used.Where(r => r == null).