c# - 如何快速输入DataTable?或者将数据永久保存到 DataTable 中?
问题描述
我将文本文件输入到 DataTable 中,然后使用 SqlBulkCopy 复制到数据库。虽然 BulkCopy 速度很快,但将 50000 多行插入 DataTable 却不是(大约 5 分钟)。我如何使它高效?
我可以快速将数据插入到 DataTable 中吗?如果没有,有没有办法将插入的数据永久保存到 DataTable 中,这样我就不必每次运行程序时都插入它?
for (; i < fares.Length; )
{
k = i;
Console.WriteLine("Inserting " + k + " out of " + (fares.Length));
for (; i <= (k + 3); i++)
{
if (i % 4 == 0)
{
for (int j = 0; j < fares.Length - 1; j++)
{
{
int space = fares[i].IndexOf(" ");
startStation = fares[i].Substring(0, space);
endStation = fares[i].Substring(space + 1, fares[i].Length - space - 1);
}
}
}
else if (i % 4 == 1)
{
valueFare = fares[i];
}
else if (i % 4 == 2)
{
standardFare = fares[i];
}
else if (i % 4 == 3)
{
time = int.Parse(fares[i]);
}
}
faresDT.Rows.Add(startStation, endStation, valueFare, standardFare, time);
解决方案
如果您想要优化对数据库的负载,我建议您完全摆脱 DataTable。通过使用 Marc Gravell 的FastMember(恕我直言,任何使用 SqlBulkCopy 的人都应该使用 FastMember),您可以直接从任何 IEnumerable 获取 DataReader。
每当从文件直接写入数据库时,我都会使用以下代码的一些变体。下面的代码将通过巧妙地使用收益返回和 IEnumerable 的延迟加载将文件的内容直接流式传输到 SqlBulkCopy 操作。
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using FastMember;
namespace BulkCopyTest
{
public class Program
{
public static void Main(string[] args)
{
const string filePath = "SOME FILE THAT YOU WANT TO LOAD TO A DB";
WriteData(GetData<dynamic>(filePath));
}
private static void WriteData<T>(IEnumerable<T> data)
{
using (var bcp = new SqlBulkCopy(GetConnection(), SqlBulkCopyOptions.TableLock, null))
using (var reader = ObjectReader.Create(data))
{
SetColumnMappings<T>(bcp.ColumnMappings);
bcp.BulkCopyTimeout = 300;
bcp.BatchSize = 150000;
bcp.DestinationTableName = ""; //TODO: Set correct TableName
bcp.WriteToServer(reader);
}
}
private static void SetColumnMappings<T>(SqlBulkCopyColumnMappingCollection mappings)
{
//Setup your column mappings
}
private static IEnumerable<T> GetData<T>(string filePath)
{
using (var fileStream = File.OpenRead(filePath))
using (var reader = new StreamReader(fileStream, Encoding.UTF8))
{
string line;
while ((line = reader.ReadLine()) != null)
{
//TODO: Add actual parsing logic and whatever else is needed to create an instance of T
yield return Activator.CreateInstance<T>();
}
}
}
private static SqlConnection GetConnection()
{
return new SqlConnection(new SqlConnectionStringBuilder
{
//TODO: Set Connection information here
}.ConnectionString);
}
}
}
推荐阅读
- google-apps-script - 如何使用谷歌脚本(以编程方式)将图像从一个表格单元格复制到谷歌文档中的另一个?
- rest - 将 Kendo UI Grid 绑定到 CRUD REST API
- jhipster - JHipster 警报未显示
- .net-core - 将 LiteDb 查询中的数据复制到列表中会导致 System.InvalidOperationException
- r - 在列而不是矩阵中获取 distm 结果
- php - 优化 PHP 中的文本/HTML 文件下载
- ruby-on-rails - ActiveModelSerializer 只显示关联的 id
- css - Flexbox 列,子项在 Edge 中超出范围
- elasticsearch - 如何基于metricbeat创建节拍
- sql - 将列从表添加到表