C# 使用SqlBulkCopy是否有比使用DataTable更快的方法?

C# 使用SqlBulkCopy是否有比使用DataTable更快的方法?,c#,sql-server,sqlbulkcopy,C#,Sql Server,Sqlbulkcopy,我将大量记录加载到我的应用程序中(100万条以上),并对它们进行大量处理。处理要求它们都在内存中 之后,我想将所有(现在已修改的)记录转储到一个空表中 加载记录只需几秒钟,我就得到了大量的MyRecord项 使用SqlBulkCopy保存也只需几秒钟 然而,SqlBulkCopy需要(我相信)一个DataTable——并且将我的记录加载到DataTable中的速度很慢——使用 dataTable.Rows.Add(myRecord.Name, myRecord.Age, ....) 有没有更快

我将大量记录加载到我的应用程序中(100万条以上),并对它们进行大量处理。处理要求它们都在内存中

之后,我想将所有(现在已修改的)记录转储到一个空表中

加载记录只需几秒钟,我就得到了大量的
MyRecord

使用
SqlBulkCopy
保存也只需几秒钟

然而,
SqlBulkCopy
需要(我相信)一个
DataTable
——并且将我的记录加载到
DataTable
中的速度很慢——使用

dataTable.Rows.Add(myRecord.Name, myRecord.Age, ....)

有没有更快的方法来执行这中间步骤?

我不知道问题出在哪里。下面的程序以秒为单位运行。我怀疑速度慢是因为读取数据而不是写入数据表

       static void Main(string[] args)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("Col A", typeof(int));
            dt.Columns.Add("Col B", typeof(string));
            dt.Columns.Add("Col C", typeof(int));
            dt.Columns.Add("Col D", typeof(string));
            dt.Columns.Add("Col E", typeof(int));
            dt.Columns.Add("Col F", typeof(string));
            dt.Columns.Add("Col G", typeof(int));
            dt.Columns.Add("Col H", typeof(string));
            dt.Columns.Add("Col I", typeof(int));
            dt.Columns.Add("Col J", typeof(string));

            DateTime begin = DateTime.Now;

            for (int i = 0; i < 7500; i++)
            {
                dt.Rows.Add(new object[] {
                    i + 10000, "b", i + 20000, "d", i + 30000, "f", i + 40000, "h", i + 50000, "i"
                });
            }

            DateTime end = DateTime.Now;

            Console.WriteLine((end - begin).ToString());

            Console.ReadLine();
        }
static void Main(字符串[]args)
{
DataTable dt=新的DataTable();
添加(“A列”,类型(int));
添加(“B列”,类型(字符串));
添加(“C列”,类型(int));
添加(“D列”,类型(字符串));
添加(“列E”,类型(int));
添加(“F列”,类型(字符串));
添加(“G列”,类型(int));
添加(“H列”,类型(字符串));
添加(“第I列”,类型(int));
添加(“第J列”,类型(字符串));
DateTime begin=DateTime.Now;
对于(int i=0;i<7500;i++)
{
dt.Rows.Add(新对象[]){
i+10000,“b”,i+20000,“d”,i+30000,“f”,i+40000,“h”,i+50000,“i”
});
}
DateTime end=DateTime.Now;
WriteLine((end-begin.ToString());
Console.ReadLine();
}

造成延迟的原因是,在将数据发送到服务器之前,必须将所有内容缓冲到数据表中。为了获得更好的性能,应该立即将记录发送到SqlBulkCopy,并让类使用自己的缓冲和批处理

SqlBulkCopy可以与IDataReader一起使用。所有ADO.NET数据读取器都实现此接口,因此您可以将从任何数据读取器读取的数据推送到SqlBulkCopy

在其他情况下,假设您有一个IEnumerable对象,您可以从包中使用Marc Grasser的ObjectReader在IEnumerable上创建IDataReader。此数据读取器不会一次加载所有数据,因此在SqlBulkCopy请求之前不会缓存任何数据:

复制Marc Grasser的示例:

IEnumerable<SomeType> data = ... 

using(var bcp = new SqlBulkCopy(connection)) 
using(var reader = ObjectReader.Create(data, "Id", "Name", "Description")) 
{ 
  bcp.DestinationTableName = "SomeTable"; 
  bcp.WriteToServer(reader); 
}
IEnumerable数据=。。。
使用(var bcp=new SqlBulkCopy(连接))
使用(var reader=ObjectReader.Create(数据,“Id”、“名称”、“描述”))
{ 
bcp.DestinationTableName=“SomeTable”;
bcp.WriteToServer(读卡器);
}

你见过(那里的家伙声称每秒100万行)吗?您的DataTable是否有任何索引、键、表达式列、约束、与其他表的关系等,或者它尽可能简单?我的DataTable非常简单,有些字符串,int和datetime字段没有任何额外内容?删除,因为在使用这些答案进行调查后,发现问题是一个简单的查找在基准代码中遇到了问题。@MethodMan至于“简单的可怕过程”,我现在正在加载8个不同系统的数据-数据库、FTP、S3文件、IATA热文件(特殊解析),屏幕抓取、web服务(ie XML)、REST服务,在SSIS数据流中匹配它们以发现差异。我甚至使用TPL数据流来解析文本文件,转换它们并将它们插入数据库,同时将它们写入文本文件以进行导入。TPL数据流也允许我并行处理多个请求,例如一次处理10个REST查询