65.9K
CodeProject 正在变化。 阅读更多。
Home

Cinchoo ETL - 比较两个 CSV 文件以查找新增、更改或删除的记录(主文件 vs 详细文件)

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2021年12月13日

CPOL

2分钟阅读

viewsIcon

6042

如何使用 Cinchoo ETL 比较两个 CSV 文件,以查找新增、删除和更改的记录

1. 引言

ChoETL 是一个用于 .NET 的开源 ETL(提取、转换和加载)框架。它是一个基于代码的库,用于从多个来源提取数据,进行转换,并将其加载到 .NET 环境中的您自己的数据仓库中。您可以很快地将数据放入您的数据仓库中。

本文介绍如何使用 Cinchoo ETL 框架比较两个 CSV 文件,以查找新增、删除和更改的记录。它非常易于使用,只需几行代码即可完成比较。由于操作是基于流的,因此可以轻松比较大型文件,速度很快且内存占用量低。

2. 要求

这个框架库是用 C# 编写的,使用 .NET 4.5 / .NET Core 3.x 框架。

3. 如何使用

3.1 示例数据

让我们从查看以下示例 CSV 文件开始。假设这些 CSV 文件很大,包含不同的字段,并且它们的列数可能不同。

图 3.1.1. 主 CSV 文件 (master.csv)
ID,name
1,Danny
2,Fred
3,Sam
图 3.1.2. 详细文件 (detail.csv)
ID,name
1,Danny
3,Pamela
4,Fernando

成功比较后,应生成如下 CSV 文件

在此,我们捕获了比较操作的状态,并将它们输出到文件中。

图 3.1.3. CSV 输出 (output.csv)
ID,name,Status
1,Danny,Unchanged
2,Fred,Deleted
3,Pamela,Changed
4,Fernando,New

首先要做的是安装 ChoETL / ChoETL.NETStandard nuget 包。为此,请在包管理器控制台中运行以下命令。

.NET Framework

Install-Package ChoETL

.NET Core

Install-Package ChoETL.NETStandard

现在将 ChoETL 命名空间添加到程序。

using ChoETL;

3.2 比较操作

由于输入文件可能很大,我们需要考虑有效地合并它们的方法。这里有一种适应合并此类 CSV 文件的方法。

  1. 首先,打开每个 CSV 文件(主 CSV 文件和详细 CSV 文件),并将它们放入变量中。
  2. 然后,打开 ChoCSVWriter 以进行写入。
  3. 最后,在输入 CSV 文件流上调用 Compare 扩展方法进行比较。在这里,指定 key(“ID”)列以及 compare (“name”)列。Key 列用于匹配 CSV 文件之间的记录。Compare 列用于查找匹配记录中是否有任何更改。Compare 操作产生 Tuple<Master, Detail, Status> 记录。

其中 CompareStatus 枚举包含以下状态

  • Unchanged
  • Changed
  • 新建
  • Deleted
图 3.2.1. 比较主文件 - 详细文件
private static void CompareCSVFiles()
{
    //Open master CSV file
    var r1 = ChoCSVReader.LoadText("master.csv").
             WithFirstLineHeader().WithMaxScanRows(1).OfType<ChoDynamicObject>();

    //Open detail CSV file
    var r2 = ChoCSVReader.LoadText("detail.csv").
             WithFirstLineHeader().WithMaxScanRows(1).OfType<ChoDynamicObject>();

    //Open final output CSV file
    using (var w = new ChoCSVWriter(Console.Out).WithFirstLineHeader())
    {
        //Compare Master and Detail records
        foreach (var t in r1.Compare(r2, "ID", "name" ))
        {
            dynamic v1 = t.MasterRecord as dynamic;
            dynamic v2 = t.DetailRecord as dynamic;

            //Check on the status and capture it
            if (t.Status == CompareStatus.Unchanged || t.Status == CompareStatus.Deleted)
            {
                v1.Status = t.Status.ToString();
                w.Write(v1);
            }
            else 
            {
                v2.Status = t.Status.ToString();
                w.Write(v2);
            }
        }
    }
}

示例 fiddle: https://dotnetfiddle.net/uPR5Sq

有关 Cinchoo ETL 的更多信息,请访问其他 CodeProject 文章。

历史

  • 2021年12月13日:初始版本
© . All rights reserved.