左连接LINQ有问题

时间:2012-12-17 07:21:20

标签: c# linq datatable left-join

我有两个DataTable t1t2。我正在尝试执行LINQ左连接,多个等值连接,以使t1中的数据行不在t2中。

在SQL中,我想要完成的是:

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

到目前为止,我有以下内容:

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;
        }

这条消息在行j_a = join_row["a"]上失败: Column 'a' does not belong to table.

我认为into leftJoinT1withoutT2行应该将连接的结果放入具有表t1的列结构的var中,使用{{{}}将从中删除不匹配的条目1}}。那不是这里发生的事吗?我有点困惑。

1 个答案:

答案 0 :(得分:1)

它应该是这样的:

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(r => r == null)
            select new
            {
                j_a = t1_row["a"],
                j_b = t1_row["b"],
                j_c = t1_row["c"],
            };

查看How to: Perform Left Outer Joins (C# Programming Guide)

join_row中没有匹配元素时,null获取TSource(即默认t2值,请参阅Enumerable.DefaultIfEmpty),而t1_row }始终包含连接值。因此,只要您需要join_rownull的行,我就使用了.Where(r => r == null)