Обновление нескольких строк Linq vs SQL

Некоторое время назад я написал фрагмент кода для обновления нескольких строк в таблице базы данных. Код был таким:

var db = new MyDataContext(); db.Execute("UPDATE Details SET IsActive = 0 WHERE MasterId = 1"); 

Тогда на днях, когда я получил последнюю версию файла, я увидел, что кто-то изменил код на что-то вроде этого

 var details = from d in db.details where d.MasterId == 1 select d; foreach (var detail in details) detail.IsActive = false; db.SubmitChanges(); 

Поэтому мой вопрос: какой лучший способ обновить несколько строк? Использование Linq или SQL?

Проверьте подход, используемый в этой статье:

  • Пакетное обновление и удаление с помощью LINQ to SQL

Я бы сказал, это зависит от того, важна ли эффективность или абстракция из базы данных. SQL-путь будет создавать зависимость в вашем коде, который сложнее отслеживать, но более эффективен. Образец цитирования LINQ удаляет зависимость от SQL с ручным кодированием, но включает как минимум 2 запроса и некоторую обработку на стороне сервера.

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

 context.Task.Update(t => t.Id == 1, t2 => new Task {StatusId = 2}); 

Это выполнит Update Task Set StatusId = 2 Where Id = 1

 for (int i = 0; i < pListOrderDetail.Count; i++) { for (int j = 0; j < stempdata.Count; j++) { pListOrderDetail[i].OrderID = pOrderID; pListOrderDetail[i].ProductID = stempdata[j].pProductID; pListOrderDetail[i].Quantity = stempdata[j].pQuantity; pListOrderDetail[i].UnitPrice = stempdata[j].pUnitPrice; pListOrderDetail[i].Discount = stempdata[j].pDiscount; db.SubmitChanges(); break; } continue; } 

Версия Linq-to-SQL будет SELECT каждую строку из таблицы details которая соответствует запросу, вытаскивает их в память и создает для них объекты. Затем, когда он применяет обновления, он будет использовать отдельный оператор UPDATE для каждого объекта и будет (по умолчанию) включать предложение WHERE , которое проверяет значение каждого столбца, чтобы убедиться, что оно не изменилось с тех пор, как вы сделали SELECT . Если строка изменилась, Linq выдает исключение.

Версия кода Linq будет намного медленнее (думаю, на 100x или 1000x медленнее), и предоставит вам дополнительные исключения.

Версия SQL может быть немного сложнее поддерживать в качестве кода рефакторинга в будущем, но это сделает мир различий в вашей базе данных.

Я обычно чувствую, что Linq-to-SQL отлично подходит для выборок и отдельных обновлений, и, возможно, для небольших партий база данных будет достаточно быстрой, чтобы дополнительные запросы не были проблемой, но я должен был бы тщательно подумать, прежде чем использовать Linq для больших партий или на веб-сервере.