You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 19:45:09