Вам действительно нужно приложение для этого? Наиболее эффективным способом будет просто выполнить оператор SQL на сервере, который передает данные между таблицами.
SqlBulkCopy должен быть достаточно быстрым с одним потоком. Для лучшей производительности рассмотрите загрузку данных с помощью устройства чтения данных и его декорирование (шаблон декоратора) классом, который выполняет требуемое преобразование. Затем вы передаете оформленный IDataReader в SqlBulkCopy, чтобы получить непрерывный поток данных между таблицами, который будет поддерживать низкую нагрузку на память и завершить передачу в считанные секунды.
Пример: входная таблица A с одним столбцом типа float и выходная таблица B с одним столбцом типа float. Мы извлечем все числа из таблицы A и вставим квадратный корень каждого неотрицательного числа в таблицу B.
class SqrtingDataDecorator : IDataReader
{
private readonly IDataReader _decorated;
private double _input;
public SqrtingDataDecorator(IDataReader decorated)
{
_decorated = decorated;
}
public bool Read()
{
while (_decorated.Read())
{
_input = _decorated.GetDouble(0);
if (_input >= 0)
return true;
}
return false;
}
public object GetValue(int index)
{
return Math.Sqrt(_input);
}
public int FieldCount { get { return 1; } }
//other IDataReader members just throw NotSupportedExceptions,
//return null or do nothing. Omitted for clarity.
}
Вот бит, который делает работу
//get the input datareader
IDataReader dr = ///.ExecuteDataReader("select floatCol from A", or whatever
using (SqlTransaction tx = _connection.BeginTransaction())
{
try
{
using (SqlBulkCopy sqlBulkCopy =
new SqlBulkCopy(_connection, SqlBulkCopyOptions.Default, tx))
{
sqlBulkCopy.DestinationTableName = "B";
SetColumnMappings(sqlBulkCopy.ColumnMappings);
//above method omitted for clarity, easy to figure out
//now wrap the input datareader in the decorator
var sqrter = new SqrtingDataDecorator(dr);
//the following line does the data transfer.
sqlBulkCopy.WriteToServer(sqrter);
tx.Commit();
}
}
catch
{
tx.Rollback();
throw;
}
}