因此,在将 MySqlDataReader 与 BLOB 列一起使用时,我遇到了臭名昭著的IndexOutOfRangeException 。我的情况虽然很具体。故事如下。我首先通过执行命令获取 MySqlDataReader,然后将其传递给 SqlBulkCopy 以进行“流式”批量插入,从而将数据从 MySQL 拉入 SQL Server。代码简单明了:
public static void BulkCopyMySqlDataReader(string destinationConnectionString, int batchSize, string destinationTableName, IEnumerable<string> sourceColumns, MySqlDataReader mySqlDataReader)
{
using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnectionString, SqlBulkCopyOptions.TableLock | SqlBulkCopyOptions.Default))
{
bulkCopy.BulkCopyTimeout = 0;
bulkCopy.BatchSize = batchSize;
bulkCopy.DestinationTableName = destinationTableName;
bulkCopy.EnableStreaming = true;
foreach (var dataColumn in sourceColumns)
_ = bulkCopy.ColumnMappings.Add(dataColumn, dataColumn);
try
{
bulkCopy.WriteToServer(mySqlDataReader);
}
catch (Exception)
{
throw;
}
}
}
一切正常,但是,在 MySQL 方面,我有 2 个带有 BLOB 列的表,这就是问题开始的地方。加载这些表时,它会抛出:
System.IndexOutOfRangeException: Data index must be a valid index in the field
System.IndexOutOfRangeException:
at MySql.Data.MySqlClient.Interceptors.ExceptionInterceptor.Throw(Exception exception)
at MySql.Data.MySqlClient.MySqlDataReader.Throw(Exception ex)
at MySql.Data.MySqlClient.MySqlDataReader.GetBytes(Int32 i, Int64 fieldOffset, Byte[] buffer, Int32 bufferoffset, Int32 length)
因此,据我了解,SqlBulkCopy 决定自己必须调用 GetBytes() 方法来流式传输 BLOB 列的数据,这就是我得到这个异常的地方。由于特定原因,我绑定到版本 8.0.15 的 MySql.Data 库。因此,即使它在较新的版本中得到修复,我也必须以某种方式自己处理它。我的想法是以某种方式覆盖 GetBytes() 以克服这个问题。
由于 MySqlDataReader 是密封的,因此无法从它继承。所以,我正在考虑使用装饰器模式并喜欢:
public sealed class MySqlDataReaderFixed : DbDataReader, IDataReader, IDisposable, IDataRecord
{
public MySqlDataReader mySqlDataReader { get; set; }
//override required methods like...
public override bool GetBoolean(int ordinal)
{
return mySqlDataReader.GetBoolean(ordinal);
}
}
那么,我该如何正确执行 GetBytes() 呢?即在我的 MySqlDataReaderFixed 类中应该有什么:
public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length)
{
var bufferLength = mySqlDataReader.GetBytes(ordinal, 0, null, 0, 0);
// what's next?
}
有人可以帮忙吗?或者,也许还有另一种解决问题的方法,考虑仍然使用 MySqlDataReader(来自 MySql.Data v 8.0.15.0)和 SqlBulkCopy?