我正在尝试将大量记录插入到各种表中。我无法同时将所有记录放入内存中,因此我使用IDataReader
实现将一些数据放入内存中,然后使用SqlBulkCopy
将其转储到数据库中。
我遇到的问题是,第二次尝试写入表时,SqlBulkCopy
将成功但无法实际插入记录。我一开始认为这是一个交易问题,但我在我的连接上禁用了所有交易,但我仍然看到同样的问题。我还可以在代码内部和外部之前和之后独立地确认表的大小。
以下是代码段:
long before = GetCount(tableName);
DataServerConnection conn = GetConnection();
using (var batch = conn.HasTransaction ?
new SqlBulkCopy((SqlConnection)conn.IDbConnection, SqlBulkCopyOptions.Default, (SqlTransaction)conn.Transaction) :
new SqlBulkCopy((SqlConnection)conn.IDbConnection))
{
batch.DestinationTableName = tableName;
batch.WriteToServer(reader);
}
long after = GetCount(tableName);
if ((reader.Count + before) != after)
{
throw new Exception($"Not all records inserted: Before = {before}, After = {after}, Reader Count = {reader.Count}, Expected = {reader.Count + before}");
}
我缺少什么想法? GetCount(tableName)
正在做一个简单的
SELECT COUNT(*) FROM [{tableName}]
reader
是一个基本的IDataReader
实现,我已经验证了在数百万条记录中的其他位置。 GetConnection()
正在为连接返回一个包装器,这有助于防止我不断地管理我的连接。
答案 0 :(得分:0)
我不确定你的读者变量是如何声明的所以我会告诉你我有时会这样做(这并不意味着它是最好的方法)。
首先,我根据我拥有的数据集声明一个tableAdapter:
DataSetTableAdapter.MyTableAdapter dataTable = new DataSetTableAdapter.MyTableAdapter();
然后,我创建连接。
SqlConnection sql = new SqlConnection(...);
然后是BulkCopy变量:
SqlBulkCopy insertData = new SqlBulkCopy(sql);
有了这个,我就开始在表适配器中添加行:
dataTable.AddMyTableRow(...);
当我完成后,我会进行批量插入:
sql.Open();
insertData.DestinationTableName = "MyTable";
insertData.WriteToServer(dataTable);
sql.Close();
如果这有助于您,请告诉我。