C# Linq-如何在where子句中使用2列
我有两个数据表,我想使用linq从第一个表中选择第二个表中不存在的行,这些行基于两列(col1,col2) 请检查下面的示例 我尝试了这个页面上的例子 从示例中,它们仅用于一列 编辑1 我试过了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",
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();
}