使用ChoETL对比两个CSV文件结果异常的技术求助
解决ChoETL CSV对比结果格式与状态标记异常问题
问题核心
使用ChoETL对比两个CSV文件时,出现两个关键问题:
- 输出的CSV分隔符变为分号(
;)而非预期的逗号(,) - 状态标记完全错误,所有记录被错误标记为
New或Deleted,未生成预期的Unchanged、Changed状态
原因分析
- 分隔符自动推断问题:ChoCSVWriter默认会根据环境或扫描内容自动选择分隔符,未明确指定时可能出现不符合预期的分隔符。
- 状态处理逻辑错误:
- 未将
CompareStatus.Added映射为预期的New状态文本 - 记录选择逻辑存在偏差,导致错误输出对应记录
- 未将
- 动态属性赋值方式问题:直接给
ChoDynamicObject动态赋值Status属性,可能未被ChoETL正确识别并纳入输出字段。
修正方案与代码
以下是修正后的完整代码,解决了上述所有问题:
static void Main(string[] args) { string csv1 = @"ID,name 1,Danny 2,Fred 3,Sam"; string csv2 = @"ID,name 1,Danny 3,Pamela 4,Fernando"; var r1 = ChoCSVReader.LoadText(csv1) .WithFirstLineHeader() .WithMaxScanRows(1) .OfType<ChoDynamicObject>(); var r2 = ChoCSVReader.LoadText(csv2) .WithFirstLineHeader() .WithMaxScanRows(1) .OfType<ChoDynamicObject>(); using (var w = new ChoCSVWriter(Console.Out) .WithFirstLineHeader() .WithDelimiter(',')) // 强制指定逗号分隔符 { foreach (var compareResult in r1.Compare(r2, "ID", "name")) { dynamic outputRecord = null; string status = compareResult.Status.ToString(); // 将Added状态转换为预期的New文本 if (compareResult.Status == CompareStatus.Added) status = "New"; // 根据对比状态选择对应记录 switch (compareResult.Status) { case CompareStatus.Unchanged: case CompareStatus.Deleted: outputRecord = compareResult.MasterRecord; break; case CompareStatus.Changed: case CompareStatus.Added: outputRecord = compareResult.DetailRecord; break; } // 通过字典接口为动态对象添加Status属性,确保被Writer识别 ((IDictionary<string, object>)outputRecord).Add("Status", status); w.Write(outputRecord); } } Console.ReadLine(); }
关键修正点说明
- 强制指定分隔符:通过
.WithDelimiter(',')明确指定CSV输出的分隔符为逗号,彻底解决分隔符异常问题。 - 状态文本映射:将
CompareStatus.Added转换为"New",匹配预期的状态标记文本。 - 正确选择输出记录:
Unchanged/Deleted状态:输出原CSV1(Master)的记录Changed/Added(New)状态:输出原CSV2(Detail)的记录
- 规范动态属性添加:利用
IDictionary<string, object>接口给ChoDynamicObject添加属性,确保ChoETL能够正确识别并输出该字段。
内容的提问来源于stack exchange,提问作者Eraaz
相关产品推荐
相关产品推荐

