C#实现DataTable匹配行复制至目标表、不匹配行存入另一表的问题
解决DataTable匹配与拆分的问题
我来帮你搞定这个需求!你需要先确保目标表dt3和dt4的结构和dt1完全一致,再通过LINQ筛选出匹配/不匹配的行,最后把这些行导入到对应的表中。下面是完整的实现步骤和代码:
步骤1:复制DataTable结构
首先我们需要克隆dt1的表结构(只复制列,不包含数据),这样后续添加行的时候不会出现结构不匹配的错误:
// 克隆dt1的结构到dt3和dt4 DataTable dt3 = dt1.Clone(); DataTable dt4 = dt1.Clone();
步骤2:提取dt2的ID集合(优化查询效率)
为了快速判断dt1的行是否匹配,我们把dt2中的ID提取到一个HashSet里——HashSet的查找效率远高于每次遍历dt2,数据量大的时候效果更明显:
// 提取dt2中的所有Id到HashSet var dt2IdSet = new HashSet<int>(dt2.AsEnumerable().Select(row => row.Field<int>("Id")));
步骤3:筛选匹配与不匹配的行
用LINQ从dt1中分别筛选出ID在dt2IdSet里的匹配行,以及不在里面的不匹配行:
// 筛选dt1中与dt2 ID匹配的行 var matchingRows = dt1.AsEnumerable().Where(row => dt2IdSet.Contains(row.Field<int>("Id"))); // 筛选dt1中与dt2 ID不匹配的行 var nonMatchingRows = dt1.AsEnumerable().Where(row => !dt2IdSet.Contains(row.Field<int>("Id")));
步骤4:将行导入目标表
使用ImportRow()方法把筛选后的行导入到dt3和dt4中,这个方法会完整复制行的所有数据和状态(比如行的修改状态):
// 导入匹配行到dt3 foreach (var row in matchingRows) { dt3.ImportRow(row); } // 导入不匹配行到dt4 foreach (var row in nonMatchingRows) { dt4.ImportRow(row); }
完整代码示例
把上面的步骤整合起来,就是完整的可运行代码:
// 假设dt1和dt2已经初始化并填充了数据 DataTable dt3 = dt1.Clone(); DataTable dt4 = dt1.Clone(); var dt2IdSet = new HashSet<int>(dt2.AsEnumerable().Select(row => row.Field<int>("Id"))); var matchingRows = dt1.AsEnumerable().Where(row => dt2IdSet.Contains(row.Field<int>("Id"))); var nonMatchingRows = dt1.AsEnumerable().Where(row => !dt2IdSet.Contains(row.Field<int>("Id"))); foreach (var row in matchingRows) { dt3.ImportRow(row); } foreach (var row in nonMatchingRows) { dt4.ImportRow(row); }
注意事项
- 如果你的
Id字段不是int类型(比如string),记得把Field<int>改成对应的类型,比如Field<string>。 - 如果不需要保留行的状态,也可以用
dt3.Rows.Add(row.ItemArray)来添加行,但ImportRow()的兼容性更好。
内容的提问来源于stack exchange,提问作者Mangrio
相关产品推荐
相关产品推荐

