我正在c#中编写一个单元测试,负责使用System.Data.SqlClient.SqlBulkCopy将DataTable复制到数据库服务器。
我使用SQLLite进行单元测试,并希望使用SqlBulkCopy连接到内存数据库中的SQLLite,然后将该测试数据批量复制到SQLLite数据库中。
但是,我似乎无法正确获取连接字符串。
我最初尝试过
var bcp = new SqlBulkCopy("Data Source=:memory:;Cache=Shared")
然后
Cache
哪些人无法识别var bcp = new SqlBulkCopy("Data Source=:memory:")
所以我试过
val iMax = graph.map{ g => g.i }.max
val jMax = graph.map{ g => g.j }.max
val theMax = math.max(iMax,jMax)
出于绝望,在尝试连接数据库时只是超时。
我在这里想要完成的是什么?如果是,有人可以帮我解决连接字符串吗?
答案 0 :(得分:1)
您不能将SqlBulkCopy
用于SQLite。已为SQL Server完成SqlBulkCopy
。
通常,显着提高SQLite性能的技巧是确保使用事务。
免责声明:我是.NET Bulk Operations
的所有者此库不是免费的,但允许您轻松执行和自定义所有批量操作:
实施例
// Easy to use
var bulk = new BulkOperation(connection);
bulk.BulkInsert(dt);
bulk.BulkUpdate(dt);
bulk.BulkDelete(dt);
bulk.BulkMerge(dt);
// Easy to customize
var bulk = new BulkOperation<Customer>(connection);
bulk.BatchSize = 1000;
bulk.ColumnInputExpression = c => new { c.Name, c.FirstName };
bulk.ColumnOutputExpression = c => c.CustomerID;
bulk.ColumnPrimaryKeyExpression = c => c.Code;
bulk.BulkMerge(customers);
编辑:回答评论
我想从SQLite加载数据表,然后在其他数据库中“批量复制”它
这种情况是可能的,但需要2个连接
DbConnection sourceConnection = // connection from the source
DbConnection destinationConnection = // connection from the destination
// Fill the DataTable using the sourceConnection
dt = ...;
// BulkInsert using the destinationConnection
var bulk = new BulkOperation(destinationConnection);
bulk.BulkInsert(dt);
答案 1 :(得分:1)
此问题的答案是您无法将SqlBulkCopy连接到SQLite实例。
我解决问题的方法(对使用SqlBulkCopy的部分代码进行单元测试)是围绕SqlBulkCopy创建一个包装,该包装使用SqlBulkCopy进行生产代码实现,并在测试代码中使用模拟批量复制。有效地解耦对SqlBulkCopy本身的依赖关系。
具体地说,我创建了
public interface IBulkCopy : IDisposable {
public string DestinationTableName {get;set;}
public void CreateColumnMapping(string from, string to);
public Task WriteToServerAsync(DataTable dt);
}
然后,我将其实现为
public class SQLBulkCopy : IBulkCopy {
private SqlBulkCopy _sbc;
public string DestinationTableName {
get { return _sbc.DestinationTableName; }
set { _sbc.DestinationTableName = value; }
}
public SQLBulkCopy(IDBContext ctx) {
_sbc = new SqlBulkCopy((SqlConnection)ctx.GetConnection());
}
public void CreateColumnMapping(string from, string to) {
_sbc.ColumnMappings.Add(new SqlBulkCopyColumnMapping(from, to));
}
public Task WriteToServerAsync(DataTable dt) {
return _sbc.WriteToServerAsync(dt);
}
}
在我的测试实用程序中,我只用插入内容就模拟了“批量复制”:
class MockBulkCopy : IBulkCopy {
private IDBContext _context;
public MockBulkCopyHelper(IDBContext context) {
_context = context;
}
public string DestinationTableName { get; set; }
public void CreateColumnMapping(string fromName, string toName) {
//We don't need a column mapping for raw SQL Insert statements.
return;
}
public virtual Task WriteToServerAsync(DataTable dt) {
return Task.Run(() => {
using (var cn = _context.GetConnection()) {
using (var cmd = cn.CreateCommand()) {
cmd.CommandText = $"INSERT INTO {DestinationTableName}({GetCsvColumnList(dt)}) VALUES {GetCsvValueList(dt)}";
cmd.ExecuteNonQuery();
}
}
});
}
我在GetCsvColumnList
和GetCsvValueList
处实现了辅助功能。