Обнаружение вставок LINQ перед submitChanges и использование BulkInsert вместо - PullRequest
1 голос
/ 01 ноября 2010

У меня есть куча кода, который настроен на добавление вставок 10–20 КБ в базу данных LINQ в дополнение к нескольким обновлениям / удалениям.Все эти изменения фиксируются с помощью вызова db.SubmitChanges ().Проблема в том, что он слишком медленный: (* ​​1002 * Производительность была тщательно протестирована в этом замечательном посте на StackOverflow:

Очень медленный процесс вставки с использованием Linq to Sql

Проблема в том, что я не хочу переписывать весь код, который готовит мой объект БД. Я попытался написать псевдо-код, что я хотел бы сделать ниже.

Отказ от ответственности:Это не настоящий код! Он не будет компилироваться .... даже не близко :)

СТАРЫЙ ПУТЬ:

SchedDB.Data.SchedulerDBDataContext db = new SchedDB.Data.SchedulerDBDataContext();
//Do a bunch of stuff to populate "db"
db.SubmitChanges()

НОВЫЙ ПУТЬ:

SchedDB.Data.SchedulerDBDataContext db = new SchedDB.Data.SchedulerDBDataContext();
//Do a bunch of stuff to populate "db"
//NEW: Detect all of the inserts in the "db" object.  Remove those inserts and generate code to insert them with a batch dataadapter.  For example:
//
//DataTable dtProducts = new DataTable()
//dtProducts.Columns.Add(ProductID) //yada yada all of the columns here
//
//DataTable dtCustomers = new DataTable()
//dtCustomers.Columns.Add(CustomerID) //yada yada all of the columns here


//foreach (insertItem in db.Inserts) //this is pseudo code, I need help here
//{
//   if (insertItem.destinationTable == "Products")
//   {
//      DataRow dr = dtProducts.NewRow();
//      dr["ProductID"] = insertItem.ProductID; //This line of code probably isn't even close to being right... I can't imagine the "insertItem" holding all of the columns no matter what the destinationTable is
//   }
//   if (insertItem.destinationTable == "Customers")
//   {
//       //similar code, all customer columns, yada yada
//   }
//   IMPORTANT: remove the item from the LINQ db so it doesn't insert it anymore
//
// Make a table adapter for each datatable
// Set the .BatchSize parameter
//Commit each table adapter.
// db.SubmitChanges()  //If there are any updates or deletes they are still in here and still need to happen.

Если в массовых обновлениях есть какие-либо ошибки, было бы неплохо знать, что я могу откатить базу данных LINQ и, возможно, запустить какой-нибудь другой код для очистки вставок dataapapters.(Я могу справиться с этим, у всех моих вставок есть дополнительный столбец, который является уникальным для пакетной вставки.)

Ответы [ 2 ]

2 голосов
/ 06 ноября 2010

ОК, я нашел ответ на свой вопрос.Классный класс, который вы можете скачать здесь:

http://code.msdn.microsoft.com/LinqEntityDataReader

Этот класс идеально подходит для меня, я могу просто передать коллекцию объектов "Клиент", сгенерированных LINQ, в SQLBulkCopy!

0 голосов
/ 01 ноября 2010

Вместо того, чтобы делать все это, почему бы просто не вставить db.SubmitChanges (); звонки после каждого отдельного предмета или после блоков X предметов? Это тоже не идеально, но лучше, чем отправлять массивные изменения одновременно, и потенциально очень легко изменить в коде.

Подача обновлений умеренного размера DataContext, и это на самом деле не делает плохую работу, выполняя их за вас. Затем перейдите к более продуктивным вещам.

...