如何使用ChoETL对比两个CSV文件以识别新增、修改、删除的记录
ChoETL CSV差异对比实现方案
完整可运行代码
using System; using ChoETL; using System.Linq; using System.Collections.Generic; public class Program { public static void Main() { // 加载主表、明细表数据 var masterRecords = ChoCSVReader.LoadText(masterCsv).WithFirstLineHeader().OfType<ChoDynamicObject>().ToArray(); var detailRecords = ChoCSVReader.LoadText(detailCsv).WithFirstLineHeader().OfType<ChoDynamicObject>().ToArray(); // 按ID建立索引字典,提升查找效率 var masterDict = masterRecords.ToDictionary(r => (long)r.ID, r => r); var detailDict = detailRecords.ToDictionary(r => (long)r.ID, r => r); // 收集两个表所有的唯一ID并排序 var allIds = masterDict.Keys.Union(detailDict.Keys).OrderBy(id => id).ToList(); var resultList = new List<dynamic>(); // 逐ID判断状态 foreach (var id in allIds) { bool hasMaster = masterDict.TryGetValue(id, out var masterRec); bool hasDetail = detailDict.TryGetValue(id, out var detailRec); var outputRec = new ChoDynamicObject(); if (!hasMaster && hasDetail) { // 新增记录:取明细表数据 outputRec.ID = id; outputRec.name = detailRec.name; outputRec.status = "NEW"; } else if (hasMaster && !hasDetail) { // 删除记录:取主表数据 outputRec.ID = id; outputRec.name = masterRec.name; outputRec.status = "DELETED"; } else { // 两边都存在,对比字段判断是否变更 bool isChanged = !masterRec.name.Equals(detailRec.name); // 如需适配更多字段,可替换为动态遍历逻辑: // bool isChanged = masterRec.GetDynamicMemberNames().Any(key => !masterRec[key].Equals(detailRec[key])); outputRec.ID = id; outputRec.name = detailRec.name; outputRec.status = isChanged ? "CHANGED" : "NOCHANGE"; } resultList.Add(outputRec); } // 输出结果 Console.WriteLine("CHANGED records\n"); using (var output = new ChoCSVWriter(Console.Out).WithFirstLineHeader()) { output.Write(resultList); } } static string masterCsv = @" ID,name 1,Danny 2,Fred 3,Sam"; static string detailCsv = @" ID,name 1,Danny 3,Pamela 4,Fernando"; }
运行输出结果
CHANGED records ID,name,status 1,Danny,NOCHANGE 2,Fred,DELETED 3,Pamela,CHANGED 4,Fernando,NEW
关键调整说明
- 放弃原有
Except对比逻辑,改用全ID遍历的方式覆盖所有可能的记录,避免状态识别错误 - 用字典存储两张表的记录,按ID索引,大幅提升查找效率,适配大文件对比场景
- 新增状态判断分支,分别匹配新增、删除、变更、无变更四种状态
- 动态为输出记录添加
status字段,直接符合要求的输出格式 - 预留多字段适配逻辑,后续CSV新增字段不需要修改核心判断代码,可直接复用
内容的提问来源于stack exchange,提问作者Fandango68
相关产品推荐
相关产品推荐

