首页 > 解决方案 > Linq - 如何在 where 子句中使用 2 列

问题描述

我有两个数据表,我想使用 linq 基于 2 列(col1,col2)从第一个表中选择第二个表中不存在的行

请检查以下示例

在此处输入图像描述

我尝试了此页面中的示例 比较两个数据表并选择第二个表中不存在的行

从示例中它们仅使用一列

编辑 1 我试过

        DataTable Table1 = new DataTable();
        Table1.Columns.Add("col1", typeof(string));
        Table1.Columns.Add("col2", typeof(string));

        DataRow r1 = Table1.NewRow();
        r1["col1"] = "A";
        r1["col2"] = "A-1";
        Table1.Rows.Add(r1);

        DataRow r2 = Table1.NewRow();
        r2["col1"] = "B";
        r2["col2"] = "B-2";
        Table1.Rows.Add(r2);

        DataRow r3 = Table1.NewRow();
        r3["col1"] = "C";
        r3["col2"] = "C-3";
        Table1.Rows.Add(r3);

        DataRow r4 = Table1.NewRow();
        r4["col1"] = "D";
        r4["col2"] = "D-4";
        Table1.Rows.Add(r4);

        DataRow r5 = Table1.NewRow();
        r5["col1"] = "E";
        r5["col2"] = "E-5";
        Table1.Rows.Add(r5);


        DataTable Table2 = new DataTable();
        Table2.Columns.Add("col1", typeof(string));
        Table2.Columns.Add("col2", typeof(string));

        DataRow r11 = Table2.NewRow();
        r11["col1"] = "A";
        r11["col2"] = "A-1";
        Table2.Rows.Add(r11);

        DataRow r22 = Table2.NewRow();
        r22["col1"] = "B";
        r22["col2"] = "B-2";
        Table2.Rows.Add(r22);

        DataRow r33 = Table2.NewRow();
        r33["col1"] = "C";
        r33["col2"] = "C-4";
        Table2.Rows.Add(r33);

        DataRow r44 = Table2.NewRow();
        r44["col1"] = "D";
        r44["col2"] = "DD";
        Table2.Rows.Add(r44);

        DataRow r55 = Table2.NewRow();
        r55["col1"] = "E";
        r55["col2"] = "EE";
        Table2.Rows.Add(r55);

        DataRow r66 = Table2.NewRow();
        r66["col1"] = "F";
        r66["col2"] = "FF";
        Table2.Rows.Add(r66);

示例 - 1

DataTable table3s = (from a in Table1.AsEnumerable()
                             where !Table2.AsEnumerable().Any(e => (e.Field<string>("col1") == a.Field<string>("col1"))
                             && (e.Field<string>("col2") == a.Field<string>("col2")))
                             select a).CopyToDataTable();

示例 - 2

 DataTable TableC = Table1.AsEnumerable().Where(ra => !Table2.AsEnumerable()
                            .Any(rb => rb.Field<string>("col1") == ra.Field<string>("col1")
                            && rb.Field<string>("col2") == ra.Field<string>("col2"))).CopyToDataTable();

示例 1 和 2 在没有匹配行时给出错误

源不包含 DataRows

请根据我的示例代码给出工作示例并建议最有效的方法,因为 DataTable 可能包含大记录,如 10000 行、20000 行等

标签: c#linqdatatable

解决方案


或者使用 Any 来获得具有适当外连接而没有隐式循环的东西:

        var res = from a in Table1
            join b in Table2
                on (a.col1, a.col2) equals (b.col1, b.col2)
                into temp
            from b in temp.DefaultIfEmpty(default)
            where b.col2 == null
            select a;

它只是使用复合键连接两个表并将其放入临时表中。然后它执行外连接 ( DefaultIfEmpty) 并仅从 Table1 中获取连接返回空结果的那些条目。


推荐阅读