SqlBulkCopy Вставка нескольких таблиц в рамках одной транзакции ИЛИ операция массовой вставки между Entity Framework и CC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 SqlBulkCopy Вставка нескольких таблиц в рамках одной транзакции ИЛИ операция массовой вставки между Entity Framework и C

Сообщение Anonymous »

У меня есть две таблицы, которые необходимо вставить при запуске моего приложения.

Предположим, у меня есть следующие таблицы
  • tbl_FirstTable и tbl_SecondTable
Моя проблема — объем данных.

Мне нужно вставить поверх 10 000 строк для tbl_FirstTable и более 500 000 строк в tbl_SecondTable.

Поэтому я использую структуру сущностей следующим образом.

Код: Выделить всё

public bool Save_tbl_FirstTable_Vs_tbl_SecondTable(List List_tbl_FirstTable, List List_tbl_SecondTable)
{
bool IsSuccessSave = false;
try
{
using (DummyDBClass_ObjectContext _DummyDBClass_ObjectContext = new DummyDBClass_ObjectContext())
{
foreach (tbl_FirstTable _tbl_FirstTable in List_tbl_FirstTable)
{
_DummyDBClass_ObjectContext.tbl_FirstTable.InsertOnSubmit(_tbl_FirstTable);
}

foreach (tbl_SecondTable _tbl_SecondTable in List_tbl_SecondTable)
{
_DummyDBClass_ObjectContext.tbl_SecondTable.InsertOnSubmit(_tbl_SecondTable);
}

_DummyDBClass_ObjectContext.SubmitChanges();
IsSuccessSave = true;
}
}
catch (Exception ex)
{
Log4NetWrapper.WriteError(string.Format("{0} : {1} : Exception={2}",
this.GetType().FullName,
(new StackTrace(new StackFrame(0))).GetFrame(0).GetMethod().Name.ToString(),
ex.Message.ToString()));

if (ex.InnerException != null)
{
Log4NetWrapper.WriteError(string.Format("{0} : {1} : InnerException Exception={2}",
this.GetType().FullName,
(new StackTrace(new StackFrame(0))).GetFrame(0).GetMethod().Name.ToString(),
ex.InnerException.Message.ToString()));
}
}

return IsSuccessSave;
}
Именно здесь я сталкиваюсь с ошибкой Тайм-аут исключения.

Я думаю, что это исключение будет решено, если я использую код ниже .

Код: Выделить всё

DummyDBClass_ObjectContext.CommandTimeout = 1800; // 30 minutes
Итак, я использовал его. Это решено, но я столкнулся с другой ошибкой OutOfMemory Exception.

Поэтому я искал решения и, к счастью, нашел статьи ниже.
  • Проблема с массовой вставкой с использованием Entity Framework
  • Использование транзакций с SqlBulkCopy
  • Выполнение операции массового копирования в транзакции
  • Выполнение операции массового копирования в транзакции
  • ли>
В соответствии с этими статьями я меняю свой код с Entity Framework на классический код ADO.net.

Код: Выделить всё

public bool Save_tbl_FirstTable_Vs_tbl_SecondTable(DataTable DT_tbl_FirstTable, DataTable DT_tbl_SecondTable)
{
bool IsSuccessSave = false;
SqlTransaction transaction = null;
try
{
using (DummyDBClass_ObjectContext _DummyDBClass_ObjectContext = new DummyDBClass_ObjectContext())
{
var connectionString = ((EntityConnection)_DummyDBClass_ObjectContext.Connection).StoreConnection.ConnectionString;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
using (transaction = connection.BeginTransaction())
{
using (SqlBulkCopy bulkCopy_tbl_FirstTable = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, transaction))
{
bulkCopy_tbl_FirstTable.BatchSize = 5000;
bulkCopy_tbl_FirstTable.DestinationTableName = "dbo.tbl_FirstTable";
bulkCopy_tbl_FirstTable.ColumnMappings.Add("ID", "ID");
bulkCopy_tbl_FirstTable.ColumnMappings.Add("UploadFileID", "UploadFileID");
bulkCopy_tbl_FirstTable.ColumnMappings.Add("Active", "Active");
bulkCopy_tbl_FirstTable.ColumnMappings.Add("CreatedUserID", "CreatedUserID");
bulkCopy_tbl_FirstTable.ColumnMappings.Add("CreatedDate", "CreatedDate");
bulkCopy_tbl_FirstTable.ColumnMappings.Add("UpdatedUserID", "UpdatedUserID");
bulkCopy_tbl_FirstTable.ColumnMappings.Add("UpdatedDate", "UpdatedDate");
bulkCopy_tbl_FirstTable.WriteToServer(DT_tbl_FirstTable);
}

using (SqlBulkCopy bulkCopy_tbl_SecondTable = new SqlBulkCopy(connection, SqlBulkCopyOptions.KeepIdentity, transaction))
{

bulkCopy_tbl_SecondTable.BatchSize = 5000;
bulkCopy_tbl_SecondTable.DestinationTableName = "dbo.tbl_SecondTable";
bulkCopy_tbl_SecondTable.ColumnMappings.Add("ID", "ID");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("UploadFileDetailID", "UploadFileDetailID");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("CompaignFieldMasterID", "CompaignFieldMasterID");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("Value", "Value");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("Active", "Active");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("CreatedUserID", "CreatedUserID");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("CreatedDate", "CreatedDate");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("UpdatedUserID", "UpdatedUserID");
bulkCopy_tbl_SecondTable.ColumnMappings.Add("UpdatedDate", "UpdatedDate");
bulkCopy_tbl_SecondTable.WriteToServer(DT_tbl_SecondTable);
}

transaction.Commit();
IsSuccessSave = true;
}
connection.Close();
}
}
}
catch (Exception ex)
{
if (transaction != null)
transaction.Rollback();

Log4NetWrapper.WriteError(string.Format("{0} : {1} : Exception={2}",
this.GetType().FullName,
(new StackTrace(new StackFrame(0))).GetFrame(0).GetMethod().Name.ToString(),
ex.Message.ToString()));

if (ex.InnerException != null)
{
Log4NetWrapper.WriteError(string.Format("{0} : {1} :  InnerException Exception={2}",
this.GetType().FullName,
(new StackTrace(new StackFrame(0))).GetFrame(0).GetMethod().Name.ToString(),
ex.InnerException.Message.ToString()));
}
}

return IsSuccessSave;
}
Наконец, он выполняет процесс вставки менее чем за 15 секунд для более чем 500 000 строк.

Существует две причины почему я публикую этот сценарий.
  • Я хотел бы поделиться тем, что я узнал.
  • Поскольку я не идеален, мне все еще нужно получить больше предложений от вы.
Таким образом, каждое лучшее решение будет оценено по достоинству.

Подробнее здесь: https://stackoverflow.com/questions/154 ... sert-opera
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Оптимизация для массовой вставки sql
    Anonymous » » в форуме Php
    0 Ответы
    26 Просмотры
    Последнее сообщение Anonymous
  • Пустые записи в Drupal CMS после массовой вставки
    Anonymous » » в форуме Php
    0 Ответы
    14 Просмотры
    Последнее сообщение Anonymous
  • Экранирование одинарных кавычек для массовой вставки во временную таблицу, а затем копирование в основную
    Anonymous » » в форуме Python
    0 Ответы
    35 Просмотры
    Последнее сообщение Anonymous
  • Экранирование одинарных кавычек для массовой вставки во временную таблицу, а затем копирование в основную
    Anonymous » » в форуме Python
    0 Ответы
    13 Просмотры
    Последнее сообщение Anonymous
  • Избегайте блокировки общего доступа к файлам в MS Access во время массовой вставки.
    Anonymous » » в форуме Python
    0 Ответы
    10 Просмотры
    Последнее сообщение Anonymous

Вернуться в «C#»