标签: sqlbulkcopy

使用Dapper,批量插入的时间比预期的要长

阅读本文后,我决定仔细研究一下我使用Dapper的方式.

我在一个空数据库上运行此代码

var members = new List<Member>();
for (int i = 0; i < 50000; i++)
{
    members.Add(new Member()
    {
        Username = i.toString(),
        IsActive = true
    });
}

using (var scope = new TransactionScope())
{
    connection.Execute(@"
insert Member(Username, IsActive)
values(@Username, @IsActive)", members);

    scope.Complete();
}
Run Code Online (Sandbox Code Playgroud)

花了大约20秒钟.这是2500插入/秒.不错,但考虑到博客达到45k插入/秒,也不是很好.在Dapper中有更有效的方法吗?

另外,作为旁注,通过Visual Studio调试器运行此代码需要3分钟!我认为调试器会慢一点,但我很惊讶地看到了这么多.

UPDATE

所以这

using (var scope = new TransactionScope())
{
    connection.Execute(@"
insert Member(Username, IsActive)
values(@Username, @IsActive)", members);

    scope.Complete();
}
Run Code Online (Sandbox Code Playgroud)

还有这个

    connection.Execute(@"
insert Member(Username, IsActive)
values(@Username, @IsActive)", members);
Run Code Online (Sandbox Code Playgroud)

都花了20秒.

但这需要4秒!

SqlTransaction …
Run Code Online (Sandbox Code Playgroud)

performance sqlbulkcopy dapper

64
推荐指数
3
解决办法
3万
查看次数

SqlBulkCopy插入标识列

我正在使用该SqlBulkCopy对象将数百万个生成的行插入到数据库中.唯一的问题是我插入的表有一个标识列.我已经尝试设置SqlBulkCopyOptionsto SqlBulkCopyOptions.KeepIdentity并将标识列设置为0's,DbNull.Valuenull.其中没有一个有效.我觉得我错过了一些非常简单的事情,如果有人能够启发我会很棒.谢谢!

编辑为了澄清,我没有在DataTable我导入中设置的标识值.我希望它们作为导入的一部分生成.

编辑2 这是我用来创建基础SqlBulkCopy对象的代码.

SqlBulkCopy sbc = GetBulkCopy(SqlBulkCopyOptions.KeepIdentity);
sbc.DestinationTableName = LOOKUP_TABLE;

private static SqlBulkCopy GetBulkCopy(SqlBulkCopyOptions options = 
    SqlBulkCopyOptions.Default) 
{
    Configuration cfg = WebConfigurationManager.OpenWebConfiguration("/RSWifi");
    string connString =
    cfg.ConnectionStrings.ConnectionStrings["WifiData"].ConnectionString;
    return new SqlBulkCopy(connString, options);
}
Run Code Online (Sandbox Code Playgroud)

c# sql-server sqlbulkcopy identity-insert

62
推荐指数
3
解决办法
7万
查看次数

SqlBulkCopy - 数据源中String类型的给定值无法转换为指定目标列的类型money

我在尝试从DataTable执行SqlBulkCopy时遇到此异常.

Error Message: The given value of type String from the data source cannot be converted to type money of the specified target column.
Target Site: System.Object ConvertValue(System.Object, System.Data.SqlClient._SqlMetaData, Boolean, Boolean ByRef, Boolean ByRef)
Run Code Online (Sandbox Code Playgroud)

我理解错误说的是什么,但我怎样才能获得更多信息,例如行/字段正在发生?数据表由第三方填充,最多可包含200列和最多10k行.返回的列取决于发送给第三方的请求.所有的数据表列是字符串类型.我的数据库中的列不是所有varchar,因此,在执行插入之前,我使用以下代码格式化数据表值(删除非重要代码):

//--- create lists to hold the special data type columns
List<DataColumn> IntColumns = new List<DataColumn>();
List<DataColumn> DecimalColumns = new List<DataColumn>();
List<DataColumn> BoolColumns = new List<DataColumn>();
List<DataColumn> DateColumns = new List<DataColumn>();

foreach (DataColumn Column in dtData.Columns)
{
    //--- find the field map that tells …
Run Code Online (Sandbox Code Playgroud)

c# datatable sqlbulkcopy

45
推荐指数
7
解决办法
10万
查看次数

从类型化列表中获取IDataReader

我有一List<MyObject>百万元素.(它实际上是一个SubSonic Collection,但它没有从数据库加载).

我目前正在使用SqlBulkCopy,如下所示:

private string FastInsertCollection(string tableName, DataTable tableData)
{
    string sqlConn = ConfigurationManager.ConnectionStrings[SubSonicConfig.DefaultDataProvider.ConnectionStringName].ConnectionString;
    using (SqlBulkCopy s = new SqlBulkCopy(sqlConn, SqlBulkCopyOptions.TableLock))
    {
        s.DestinationTableName = tableName;
        s.BatchSize = 5000;
        s.WriteToServer(tableData);
        s.BulkCopyTimeout = SprocTimeout;
        s.Close();
    }
    return sqlConn;
}
Run Code Online (Sandbox Code Playgroud)

我使用SubSonic的MyObjectCollection.ToDataTable()从我的集合中构建DataTable.但是,这会在内存中复制对象并且效率低下.我想使用SqlBulkCopy.WriteToServer方法,该方法使用IDataReader而不是DataTable,这样我就不会在内存中复制我的集合.

从我的列表中获取IDataReader的最简单方法是什么?我想我可以实现一个自定义数据阅读器(如http://blogs.microsoft.co.il/blogs/aviwortzel/archive/2008/05/06/implementing-sqlbulkcopy-in-linq-to-sql.aspx)但是如果不编写一堆通用代码,我必须做一些更简单的事情.

编辑:似乎没有人可以从对象集合中轻松生成IDataReader.接受当前的答案,即使我希望框架中内置的东西.

c# sql linq sqlbulkcopy

37
推荐指数
3
解决办法
2万
查看次数

是否可以将System.Transactions.TransactionScope与SqlBulkCopy一起使用?

很简单的问题:是否可以System.Transactions.TransactionScopeSqlBulkCopy?一起使用?文档事务和批量复制操作没有提到任何内容(至少从.NET 4.0开始),我的测试表明它不会自动登记TransactionScope.

.net sql-server transactionscope sqlbulkcopy

32
推荐指数
2
解决办法
6538
查看次数

超时已过期SqlBulkCopy

我正在使用SqlBulkCopy从xml备份中恢复表.其中一个表备份大约200MB,并且有很多记录.

我有错误:

Timeout expired.
The timeout period elapsed prior to completion of the operation or the server
is not responding.
Run Code Online (Sandbox Code Playgroud)

.net sql sql-server asp.net sqlbulkcopy

27
推荐指数
3
解决办法
3万
查看次数

标识列上具有父/子关系的SqlBulkCopy和DataTables

我们需要根据父表中的Identity主键更新几个具有父/子关系的表,父表由一个或多个子表作为外键引用.

  • 由于大量的数据,我们想在内存中建立这些表,然后使用SqlBulkCopy的从C#来无论从数据集或数据表单独更新数据库的连接质量.
  • 我们还希望从多个线程,进程和可能的客户端并行执行此操作.

我们在F#中的原型显示了许多承诺,性能提高了34倍,但此代码强制在父表中使用已知的Identity值.如果没有强制,当SqlBulkCopy插入行时,Identity列会在数据库中正确生成,但Identity值不会在内存中的DataTable中更新.此外,即使它们是,也不清楚DataSet是否能正确地修复父/子关系,以便随后可以用正确的外键值写入子表.

任何人都可以解释如何让SqlBulkCopy更新Identity值,以及如何配置DataSet以保留和更新父/子关系,如果在单个DataTables上调用DataAdapter到FillSchema时不自动完成.

我不想要的答案:

  • 读取数据库以查找当前最高的Identity值,然后在创建每个父行时手动递增它.不适用于多个进程/客户端,并且据我所知,失败的事务可能会导致某些标识值被跳过,因此这种方法可能会破坏关系.
  • 一次一个地写出父行,并要求返回Identity值.这通过使用SqlBulkCopy至少失去了一些收益(是的,有更多子行比父行,但仍然有很多父行).

类似于以下未回答的问题:

.net c# sql-server sqlbulkcopy

25
推荐指数
2
解决办法
2万
查看次数

完成时SQLBulkCopy行计数

我正在使用SQLBulkCopy来移动大量数据.我实现了通知事件,以便每次处理完一定数量的行时通知我,但是当作业完成时,OnSqlRowsCopied事件不会触发.如何在SQLBulkCopy writetoserver完成时获取复制的总行数?

sql-server sqlbulkcopy

23
推荐指数
6
解决办法
2万
查看次数

使用SqlBulkCopy将DataTable中的列映射到SQL表

我想知道如何在将数据添加到数据库之前将数据库表中的列映射到c#中的数据表.

using (SqlBulkCopy s = new SqlBulkCopy(conn))
{
    s.DestinationTableName = destination;
    s.WriteToServer(Ads_api_ReportData);
}
Run Code Online (Sandbox Code Playgroud)

c# sql datatable sqlbulkcopy

23
推荐指数
3
解决办法
6万
查看次数

SqlBulkCopy如何环绕外键约束?

我使用SqlBulkCopy将一组行插入到表中.我忘了在行上设置一个整数值.缺少的列用于引用另一个表,并使用外键约束强制执行此操作.

对于插入的每一行,最终整数值为零,零不识别相关表中的行.当我将值修改为有效值然后尝试将其切换回零时,它将不接受它.

所以我的问题是SqlBulkCopy如何设法让数据库处于无效状态?

sql-server foreign-keys sqlbulkcopy

23
推荐指数
2
解决办法
5984
查看次数