C# DataTable列比较并将差异写入另一列

C# DataTable列比较并将差异写入另一列,c#,datatable,closedxml,C#,Datatable,Closedxml,我正在用c语言编写一个应用程序,它可以自动比较两个不同数据库中的值 数据在两个.xlsx文件中提供。这些由最终用户加载到应用程序中。然后从这两个文件创建内存中的数据表。每人一个 现在我需要比较DataTable 1的第1列和DataTable 2的第3列。 内容的顺序不同,但它们都是数值。 有两种可能的结果: 所有单元格都匹配(但不按顺序)。换句话说,DataTable 1第1列中的所有单元格也位于DataTable 2第3列中。没有其他细胞存在 DataTable 1的第1列中存在一个单元格

我正在用c语言编写一个应用程序,它可以自动比较两个不同数据库中的值

数据在两个.xlsx文件中提供。这些由最终用户加载到应用程序中。然后从这两个文件创建内存中的数据表。每人一个

现在我需要比较DataTable 1的第1列和DataTable 2的第3列。 内容的顺序不同,但它们都是数值。 有两种可能的结果:

  • 所有单元格都匹配(但不按顺序)。换句话说,DataTable 1第1列中的所有单元格也位于DataTable 2第3列中。没有其他细胞存在

  • DataTable 1的第1列中存在一个单元格,而DataTable 2的第3列中不存在该单元格。在这种情况下,我想将这些单元格写入一个单独的工作表。我正在使用closedXML,并且已经创建并显示了工作簿

  • DataTable 2的第3列中存在一个单元格,而DataTable 1的第1列中不存在该单元格。在这种情况下,我想将这些单元格写入一个单独的工作表。我正在使用closedXML,并且已经创建并显示了工作簿

我考虑过创建一个接受两个参数的函数。两个数据表。然后对表1的第一列和表3的第三列进行比较


我正在研究的另一个解决方案是通过ClosedXML将两个数据表粘贴到工作表中。将相关列(1和3)提取到另一个单独的工作表中,并使用for each循环比较两个工作表中的所有单元格并获得差异。但是我不知道如何继续,因为我可以将不在第1列但在第3列的内容拿到工作表A,将不在第1列但在第3列的内容拿到工作表B。

您可以使用Linq查找第1列和第3列中的内容,反之亦然

您只需在项目引用中添加System.Data.DataSetExtensions,如

然后是Linq查询:

var dataTable1 = new DataTable();
dataTable1.Columns.Add(new DataColumn("Data Column 1"));

dataTable1.Rows.Add(1, "", "");
dataTable1.Rows.Add(3, "", "");
dataTable1.Rows.Add(5, "", "");
dataTable1.Rows.Add(7, "", "");
dataTable1.Rows.Add(9, "", "");

var dataTable2 = new DataTable();
dataTable2.Columns.Add(new DataColumn("Data Column 1"));
dataTable2.Columns.Add(new DataColumn("Data Column 2"));
dataTable2.Columns.Add(new DataColumn("Data Column 3"));

dataTable2.Rows.Add("", "", 1);
dataTable2.Rows.Add("", "", 2);
dataTable2.Rows.Add("", "", 4);
dataTable2.Rows.Add("", "", 6);
dataTable2.Rows.Add("", "", 7);
dataTable2.Rows.Add("", "", 8);
dataTable2.Rows.Add("", "", 9);

// Use the id of the column
var column1 = dataTable1.AsEnumerable().Select(r => r.ItemArray[0]).ToList();
var column3 = dataTable2.AsEnumerable().Select(r => r.ItemArray[2]).ToList();

// Use the name of the column
var column1WithName = dataTable1.AsEnumerable().Select(r => r.Field<string>("Data Column 1")).ToList();
var column3WithName = dataTable2.AsEnumerable().Select(r => r.Field<string>("Data Column 3")).ToList();

// All element of the Column 1 (DataTable1) that are not in Column 3 (DataTable2)
var column1Without3 = column1.Except(column3).ToList(); // [ "3", "5" ]
// All element of the Column 3 (DataTable2) that are not in Column 1 (DataTable1)
var column3Without1 = column3.Except(column1).ToList(); // [ "2", "4", "6", "8" ]
var dataTable1=newdatatable();
dataTable1.Columns.Add(新数据列(“数据列1”));
dataTable1.Rows.Add(1,“,”);
dataTable1.Rows.Add(3,“,”);
dataTable1.Rows.Add(5,“,”);
dataTable1.Rows.Add(7,“,”);
dataTable1.Rows.Add(9,“,”);
var dataTable2=新的DataTable();
dataTable2.Columns.Add(新数据列(“数据列1”));
dataTable2.Columns.Add(新数据列(“数据列2”));
dataTable2.Columns.Add(新数据列(“数据列3”));
dataTable2.Rows.Add(“,”,1);
dataTable2.Rows.Add(“,”,2);
dataTable2.Rows.Add(“,”,4);
dataTable2.Rows.Add(“,”,6);
dataTable2.Rows.Add(“,”,7);
dataTable2.Rows.Add(“,”,8);
dataTable2.Rows.Add(“,”,9);
//使用列的id
var column1=dataTable1.AsEnumerable().Select(r=>r.ItemArray[0]).ToList();
var column3=dataTable2.AsEnumerable().Select(r=>r.ItemArray[2]).ToList();
//使用列的名称
var column1WithName=dataTable1.AsEnumerable().Select(r=>r.Field(“数据列1”)).ToList();
var column3WithName=dataTable2.AsEnumerable().Select(r=>r.Field(“数据列3”)).ToList();
//第1列(DataTable1)中不在第3列(DataTable2)中的所有元素
var column1Without3=column1.Except(column3.ToList();//[ "3", "5" ]
//第3列(DataTable2)中不在第1列(DataTable1)中的所有元素
var column3Without1=column3.Except(column1.ToList();//[ "2", "4", "6", "8" ]

谢谢。就比较而言,它现在起作用了。但它总是占据数据表的最后一列。第一个数据表共有4列,第二个数据表共有6列。第一个数据表的第一列和第二个数据表的第三列是包含可比较值的列。我尝试将您的代码更改为直接索引引用,但它仍然使用DataTables的最后一列进行实际比较(因此它使用第一个DataTable的第四列和第二个DataTable的第六列)@JB1989是否更改了2个变量column1和column3的ItemArray[]?您还可以尝试使用列的名称。我在datatable1中添加了2列,代码仍然有效。通过字符串或索引位置使用列的名称并不重要。它总是从两个数据表中选取最后一列。@JB1989您能提供有关数据表的更多详细信息吗?如果我的两张桌子都能用的话,我帮不了你,但你不明白。谢谢你迄今为止的帮助。在直接从DataTable中提取相关列,然后使用您提供的LINQExcept方法之后,我实际上自己使用了传统的for-each循环解决了这个问题。由于某些原因,lambda表达式无法正常工作。尝试一个包含5列的DataTable和一个包含7列的DataTable,然后尝试使用lambda和linqexcept方法检索第1列和第3列。它将提供其他预期的输入。