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

Cinchoo ETL - 使用 SqlServer 对大型 CSV 文件进行排序

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.67/5 (3投票s)

2017年5月15日

CPOL

3分钟阅读

viewsIcon

6952

downloadIcon

94

使用Cinchoo ETL/SqlServer轻松排序大型CSV文件

1. 引言

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

本文讨论了如何使用ChoCSVReader/ChoCSVWriter组件(由ChoETL框架提供)对大型CSV文件进行排序。当需要排序时,大型CSV文件会带来挑战。如果您尝试使用.NET应用程序进行排序,则会因OutOfMemory异常而失败。使用Microsoft Excel对大型文件进行排序时,您将立即收到错误提示。

如果string排序对您有效,那么只需使用Windows SORT命令。对文件进行排序,然后就完成了。它会很乐意对您的大型CSV文件进行排序,并且使用起来很简单。

如果您需要过滤和转换文件,特别是日期/自定义类型字段,那么您将需要编写一个小型的转换程序,该程序可以将字段转换为您想要的任何内容,并重写记录。这就是Cinchoo ETL框架发挥作用的地方,它能够以您想要的方式轻松转换大型CSV文件,满足所有可能的需求,同时具有最小的内存占用和超快的性能。

在本文中,让我们学习如何使用Cinchoo ETL框架和Microsoft SQLServer来实现这一点。

要了解有关Cinchoo ETL的更多信息 - CSVReader,请访问CodeProject文章此处

2. 要求

此框架库是用 C# 编写的,使用 .NET 4.5 Framework。

3. 如何使用

3.1 示例数据

让我们从查看一个简单的示例开始,读取下面的CSV 包含四列的文件。

清单1. 示例CSV数据文件
CustId,Name,Balance,AddedDate
1732,Tom Perez,435.00,05/11/2002
5541,Pedro Gomez,12342.30,06/02/2000
1122,Mark Politti,0.00,01/02/2004
1924,Pablo Ramirez,3321.30,11/24/2002

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

Install-Package ChoETL.SqlServer

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

using ChoETL;

3.2 快速排序 - 零配置方法

此方法向您展示了如何在没有任何映射类的情况下对大型CSV文件进行排序。

清单2. 在没有映射类的情况下排序CSV文件
public static void QuickSort()
{
    using (var dr = new ChoCSVReader(@"Test.csv").WithFirstLineHeader().
        WithField("CustId", fieldType: typeof(int)).
        WithField("Name", fieldType: typeof(string)).
        WithField("Balance", fieldType: typeof(double)).
        WithField("AddedDate", fieldType: typeof(DateTime))
        )
    {
        using (var dw = new ChoCSVWriter(@"TestOut.csv"))
            dw.Write(dr.AsEnumerable().StageOnSqlServer("ORDER BY AddedDate"));
    }
}

在上面,使用ChoCSVReader对象打开输入CSV文件以进行读取。然后打开ChoCSVWriter以写入排序后的CSV文件。在reader对象上使用StateOnSqlServer()方法将数据加载到Microsoft SqlServer数据库中以进行排序操作。最后,将SQL排序表达式传递给任何CSV列的调用以对其进行排序。这将生成排序后的CSV文件。

同样,您可以在暂存数据上执行任何类型的投影、过滤或转换,同时具有最小的内存占用。

3.3 定义映射类

此方法讨论了使用映射(POCO)类对大型CSV文件进行排序。比上一步更类型安全的方法。首先,创建一个类,该类具有与CSV文件中找到的列标题名称相同的属性。下面,您将找到一个执行此操作的类的示例。

清单3. 映射类
public class Customer
{
	public int CustId { get; set; }
	public string Name { get; set; }
	public decimal Balance { get; set; }
	public DateTime AddedDate { get; set; }
}

3.3 使用ChoCSVReader/ChoCSVWriter进行排序

最后,创建一个ChoCSVReader类的实例以读取输入文件。创建一个ChoCSVWriter的实例以写入排序后的CSV文件,如下所示。

清单4. 使用映射类排序CSV文件
public static void POCOSort()
{
    using (var dr = new ChoCSVReader<Customer>(@"Test.csv").WithFirstLineHeader())
    {
        using (var dw = new ChoCSVWriter<Customer>(Console.Out))
            dw.Write(dr.AsEnumerable().StageOnSqlServer().OrderBy(x => x.AddedDate));
    }
}

在上面,代码使用reader对象上的StateOnSqlServer()方法将CSV数据加载到Microsoft SqlServer数据库中以进行排序操作。最后,对任何CSV列应用排序表达式以对其进行排序。这将生成排序后的CSV文件。

上述方法使用INSERT SQL将记录插入到数据库中,当在此操作中将大型数据文件暂存到数据库中时,可能会导致性能瓶颈。

出于同样的原因,下一个方法通过使用批量复制 (bcp) 操作将数据暂存到数据库中以进行排序操作来消除它。示例展示了如何使用它。

清单4. 使用Bcp排序CSV文件
public static void POCOSort()
{
    using (var dr = new ChoCSVReader<Customer>(@"Test.csv").WithFirstLineHeader())
    {
        using (var dw = new ChoCSVWriter<Customer>(Console.Out))
        dw.Write(dr.AsEnumerable().StageOnSqlServerUsingBcp().OrderBy(x => x.AddedDate));
    }
}

同样,您可以在暂存数据上执行任何类型的投影、过滤或转换,同时具有最小的内存占用。

有关Cinchoo ETL的更多信息,请访问下面的CodeProject文章

历史

  • 2017年5月15日:初始版本
© . All rights reserved.