阅读本文后,我决定仔细研究一下我使用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) 我正在使用该SqlBulkCopy对象将数百万个生成的行插入到数据库中.唯一的问题是我插入的表有一个标识列.我已经尝试设置SqlBulkCopyOptionsto SqlBulkCopyOptions.KeepIdentity并将标识列设置为0's,DbNull.Value和null.其中没有一个有效.我觉得我错过了一些非常简单的事情,如果有人能够启发我会很棒.谢谢!
编辑为了澄清,我没有在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) 我在尝试从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) 我有一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.接受当前的答案,即使我希望框架中内置的东西.
很简单的问题:是否可以System.Transactions.TransactionScope与SqlBulkCopy?一起使用?文档事务和批量复制操作没有提到任何内容(至少从.NET 4.0开始),我的测试表明它不会自动登记TransactionScope.
我正在使用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) 我们需要根据父表中的Identity主键更新几个具有父/子关系的表,父表由一个或多个子表作为外键引用.
我们在F#中的原型显示了许多承诺,性能提高了34倍,但此代码强制在父表中使用已知的Identity值.如果没有强制,当SqlBulkCopy插入行时,Identity列会在数据库中正确生成,但Identity值不会在内存中的DataTable中更新.此外,即使它们是,也不清楚DataSet是否能正确地修复父/子关系,以便随后可以用正确的外键值写入子表.
任何人都可以解释如何让SqlBulkCopy更新Identity值,以及如何配置DataSet以保留和更新父/子关系,如果在单个DataTables上调用DataAdapter到FillSchema时不自动完成.
我不想要的答案:
类似于以下未回答的问题:
我正在使用SQLBulkCopy来移动大量数据.我实现了通知事件,以便每次处理完一定数量的行时通知我,但是当作业完成时,OnSqlRowsCopied事件不会触发.如何在SQLBulkCopy writetoserver完成时获取复制的总行数?
我想知道如何在将数据添加到数据库之前将数据库表中的列映射到c#中的数据表.
using (SqlBulkCopy s = new SqlBulkCopy(conn))
{
s.DestinationTableName = destination;
s.WriteToServer(Ads_api_ReportData);
}
Run Code Online (Sandbox Code Playgroud) 我使用SqlBulkCopy将一组行插入到表中.我忘了在行上设置一个整数值.缺少的列用于引用另一个表,并使用外键约束强制执行此操作.
对于插入的每一行,最终整数值为零,零不识别相关表中的行.当我将值修改为有效值然后尝试将其切换回零时,它将不接受它.
所以我的问题是SqlBulkCopy如何设法让数据库处于无效状态?
sqlbulkcopy ×10
sql-server ×6
c# ×5
.net ×3
sql ×3
datatable ×2
asp.net ×1
dapper ×1
foreign-keys ×1
linq ×1
performance ×1