如何在c#中有效地比较两个数据表
本文关键字:两个 数据表 比较 有效地 | 更新日期: 2023-09-27 18:06:27
我正在研究一个方法,该方法接受两个数据表和一个主键列名列表,并返回匹配项。我没有其他关于桌子的信息。
我已经在网站上搜索了这个问题的解决方案,并找到了一些答案,但没有一个给我一个足够快的解决方案。
基于stackoverflow的结果,我现在有这个:
var matches =
(from rowA in tableA.AsEnumerable()
from rowB in tableB.AsEnumerable()
where primaryKeyColumnNames.All(column => rowA[column].ToString() == rowB[column].ToString())
select new { rowA, rowB });
问题是这真的很慢。对于两个各有8000行的表,需要4分钟。在我使用stackoverflow之前,我实际上是在遍历列和行,花了2分钟。(所以这实际上比我所拥有的要慢)2-4分钟似乎并不那么糟糕,直到我用350,000行击中表。这需要几天的时间。我需要找到更好的解决办法。
有谁能想到一个更快的方法吗?
编辑:根据tinstaafl的建议,这现在是我的代码。
var matches = tableA.Rows.Cast<DataRow>().Select(rowA => new
{
rowA,
rowB = tableB.Rows.Find(rowA.ItemArray.Where((x, y) =>
primaryKeyColumnNames.Contains(tableA.Columns[y].ColumnName,
StringComparer.InvariantCultureIgnoreCase)).ToArray())
})
.Where(x => x.rowB != null);
使用DataTable
的PrimaryKey
属性(它将接受列数组)应该会有所帮助。也许像这样:
tableA.PrimaryKey = primaryKeyColumnNames.Select(x => tableA.Columns[x]).ToArray();
tableB.PrimaryKey = primaryKeyColumnNames.Select(x => tableB.Columns[x]).ToArray();
var matches = (from System.Data.DataRow RowA in tableA.Rows
where tableB.Rows.Contains(RowA.ItemArray.Where((x,y) => primaryKeyColumnNames.Contains(tableA.Columns[y].ColumnName)).ToArray())
select RowA).ToList();
在一个包含2个表9900行并返回9800行的测试中,这花费了大约1/3秒。