C# Linq-如何在where子句中使用2列

C# Linq-如何在where子句中使用2列,c#,linq,datatable,C#,Linq,Datatable,我有两个数据表,我想使用linq从第一个表中选择第二个表中不存在的行,这些行基于两列(col1,col2) 请检查下面的示例 我尝试了这个页面上的例子 从示例中,它们仅用于一列 编辑1 我试过了 DataTable Table1 = new DataTable(); Table1.Columns.Add("col1", typeof(string)); Table1.Columns.Add("col2",

我有两个数据表,我想使用linq从第一个表中选择第二个表中不存在的行,这些行基于两列(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();
DataTable table3s=(来自表1.AsEnumerable()中的a)
其中!Table2.AsEnumerable().Any(e=>(e.Field(“col1”)==a.Field(“col1”))
&&(e.Field(“col2”)==a.Field(“col2”))
选择一个.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();
DataTable table c=Table1.AsEnumerable()。其中(ra=>!Table2.AsEnumerable())
.Any(rb=>rb.Field(“col1”)==ra.Field(“col1”)
&&rb.Field(“col2”)==ra.Field(“col2”)).CopyToDataTable();
示例1和2给出了没有匹配行时的错误

源不包含数据行

请给出基于我的示例代码的工作示例,并建议最有效的方法,因为DataTable可能包含10000行、20000行及更多的大型记录

class Table1
{
    public string col1 { get; set; }
    public string col2 { get; set; }
}

class Table2
{
    public string col1 { get; set; }
    public string col2 { get; set; }
}


或者使用以下任何方法,在没有隐式循环的情况下使用适当的外部联接:

        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
),只从表1中获取联接返回空结果的条目。

试试这个。基本上,这行代码选择表1中“col1”和“col2”值在表2中不存在的每个元素

var results = Table1.AsEnumerable().Where(t1 => Table2.AsEnumerable().All(t2 => t2["col1"] != 
    t1["col1"] || t2["col2"] != t1["col2"]));

我试图用下面的逻辑来解决这个问题。如果我遗漏了什么,请告诉我

 static void LinkPerf()
    {
        string[] arr = { "A", "B", "C", "D", "E", "F", "G", "H", "I" };

        DataTable table1 = new DataTable();

        table1.Columns.Add("Id");
        table1.Columns.Add("Col1");
        table1.Columns.Add("Col2");

        DataTable table2 = new DataTable();
        table2.Columns.Add("Id");
        table2.Columns.Add("Col1");
        table2.Columns.Add("Col2");

        DataTable ResultTable3 = new DataTable();
        ResultTable3.Columns.Add("Id");
        ResultTable3.Columns.Add("Col1");
        ResultTable3.Columns.Add("Col2");

        Random rand = new Random();
        for (int i = 1; i <= 10000; i++)
        {
            DataRow row = table1.NewRow();
            int index = rand.Next(arr.Length);
            var colVal = arr[index];

            //Table 1
            row[0] = i.ToString();
            row[1] = colVal;
            row[2] = colVal + "-" + i.ToString();
            table1.Rows.Add(row);

            //Table 2
            row = table2.NewRow();
            row[0] = i.ToString();
            row[1] = colVal;
            row[2] = (i % 5 == 0) ? colVal + colVal + i.ToString() : colVal + "-" + i.ToString();
            table2.Rows.Add(row);
        }

        Stopwatch watch = new Stopwatch();
        watch.Start();

        var result = table1.AsEnumerable()
.Where(ra => !table2.AsEnumerable()
                    .Any(rb => rb.Field<string>("Col1") == ra.Field<string>("Col1") && rb.Field<string>("Col2") == ra.Field<string>("Col2")));
        if (result.Any())
        {
            foreach (var item in result)
            {
                ResultTable3.ImportRow(item);
            }
        }
        watch.Stop();
        var timeTaken = watch.Elapsed;
        Console.WriteLine("Time taken: " + timeTaken.ToString(@"m\:ss\.fff"));
        Console.ReadLine();
    }
static void LinkPerf()
{
字符串[]arr={“A”、“B”、“C”、“D”、“E”、“F”、“G”、“H”、“I”};
DataTable1=新的DataTable();
表1.列。添加(“Id”);
表1.列。添加(“Col1”);
表1.列。添加(“Col2”);
DataTable2=新的DataTable();
表2.列。添加(“Id”);
表2.列。添加(“Col1”);
表2.列。添加(“Col2”);
DataTable ResultTable3=新DataTable();
结果表3.列。添加(“Id”);
结果表3.Columns.Add(“Col1”);
结果表3.Columns.Add(“Col2”);
Random rand=新的Random();
对于(int i=1;i!表2.AsEnumerable()
.Any(rb=>rb.Field(“Col1”)==ra.Field(“Col1”)&&rb.Field(“Col2”)==ra.Field(“Col2”));
if(result.Any())
{
foreach(结果中的var项目)
{
结果3.进口(项目);
}
}
看,停;
var TIMETAKE=观察时间已过;
Console.WriteLine(“耗时:+timetake.ToString(@“m\:ss\.fff”);
Console.ReadLine();
}

使用下面的代码:DataTable TableC=table1.AsEnumerable().Where(ra=>!table2.AsEnumerable().Any(rb=>rb.Field(“Col1”)==ra.Field(“Col1”)和&rb.Field(“Col2”)==ra.Field(“Col2”)).CopyToDataTable();根据问题1中的示例给出示例代码
var results = Table1.AsEnumerable().Where(t1 => Table2.AsEnumerable().All(t2 => t2["col1"] != 
    t1["col1"] || t2["col2"] != t1["col2"]));
 static void LinkPerf()
    {
        string[] arr = { "A", "B", "C", "D", "E", "F", "G", "H", "I" };

        DataTable table1 = new DataTable();

        table1.Columns.Add("Id");
        table1.Columns.Add("Col1");
        table1.Columns.Add("Col2");

        DataTable table2 = new DataTable();
        table2.Columns.Add("Id");
        table2.Columns.Add("Col1");
        table2.Columns.Add("Col2");

        DataTable ResultTable3 = new DataTable();
        ResultTable3.Columns.Add("Id");
        ResultTable3.Columns.Add("Col1");
        ResultTable3.Columns.Add("Col2");

        Random rand = new Random();
        for (int i = 1; i <= 10000; i++)
        {
            DataRow row = table1.NewRow();
            int index = rand.Next(arr.Length);
            var colVal = arr[index];

            //Table 1
            row[0] = i.ToString();
            row[1] = colVal;
            row[2] = colVal + "-" + i.ToString();
            table1.Rows.Add(row);

            //Table 2
            row = table2.NewRow();
            row[0] = i.ToString();
            row[1] = colVal;
            row[2] = (i % 5 == 0) ? colVal + colVal + i.ToString() : colVal + "-" + i.ToString();
            table2.Rows.Add(row);
        }

        Stopwatch watch = new Stopwatch();
        watch.Start();

        var result = table1.AsEnumerable()
.Where(ra => !table2.AsEnumerable()
                    .Any(rb => rb.Field<string>("Col1") == ra.Field<string>("Col1") && rb.Field<string>("Col2") == ra.Field<string>("Col2")));
        if (result.Any())
        {
            foreach (var item in result)
            {
                ResultTable3.ImportRow(item);
            }
        }
        watch.Stop();
        var timeTaken = watch.Elapsed;
        Console.WriteLine("Time taken: " + timeTaken.ToString(@"m\:ss\.fff"));
        Console.ReadLine();
    }