使用c#从分隔文本文件中插入SQL Server表中的批量数据

我有制表符分隔的文本文件。 文件大约100MB。 我想将此文件中的数据存储到SQL Server表。 存储在sql server中时,该文件包含100万条记录。 实现这一目标的最佳方法是什么?

我可以在c#中的momory数据表中创建,然后将其上传到sql server,但在这种情况下,它会将整个100 MB的文件加载到内存中。 如果文件大小变大怎么办?

没问题; CsvReader将处理大多数分隔的文本格式,并实现IDataReader ,因此可用于提供SqlBulkCopy 。 例如:

 using (var file = new StreamReader(path)) using (var csv = new CsvReader(file, true)) // true = first row is headers using (var bcp = new SqlBulkCopy(connectionString)) { bcp.DestinationTableName = "Foo"; bcp.WriteToServer(csv); } 

请注意, CsvReader有更多选项,更精细的文件处理(指定分隔符规则等)。 SqlBulkCopy是高性能的批量加载API – 非常高效。 这是一个流式读写器API; 它不会立即将所有数据加载到内存中。

您应该逐行读取文件,因此您不必将整行加载到内存中:

 using (var file = System.IO.File.OpenText(filename)) { while (!file.EndOfStream) { string line = file.ReadLine(); // TODO: Do your INSERT here } } 

*更新*

这将为sql server提供100万个独立的插入命令。有没有办法让它成批量

您可以使用参数化查询,它仍会发出1M插入,但仍然会非常快。

或者,您可以使用SqlBulkCopy ,但如果您不想使用第三方库,那将会非常困难。 如果您更适合MS许可证,则可以使用LINQ实体数据读取器 (在Ms-PL许可证下分发),它提供AsDataReader扩展方法:

 void MyInsertMethod() { using (var bulk = new SqlBulkCopy("MyConnectionString")) { bulk.DestinationTableName = "MyTableName"; bulk.WriteToServer(GetRows().AsDataReader()); } } class MyType { public string A { get; set; } public string B { get; set; } } IEnumerable GetRows() { using (var file = System.IO.File.OpenText("MyTextFile")) { while (!file.EndOfStream) { var splitLine = file.ReadLine().Split(','); yield return new MyType() { A = splitLine[0], B = splitLine[1] }; } } } 

如果您不想使用MS许可代码,您可以自己实现IDataReader ,但这将是一个PITA。 请注意,上面的CSV处理( Split(',') )并不健全,并且表中的列名必须与MyType上的属性名相同。 TBH,我建议你和Marc一起回答这个问题