Процедуры обновления LINQ - лучшая практика - PullRequest
2 голосов
/ 15 июля 2010

Что считается наилучшей практикой для обновлений при использовании LINQ:

  • Для создания экземпляра БД / фасада и отправить все изменения в запись за один раз?
  • Чтобы иметь статический объект db / фасад, и отправить изменения за ячейкой?

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

public static void CellName(int id, int data)
{
     using (var scope = new someDataContext())
     {
          var TableName = scope. CellName.Single(v => v.ID == id);
          TableName.CellName = data;
          scope.SubmitChanges();
     }
}

Затем их можно установить как свойство в бизнес-объекте, следуя обычной схеме TableName.CellName = [something].

Но я также делал проекты, в которых мы использовали экземплярный класс db / фасад. Где вы сначала устанавливаете новые значения, такие как свойства, а затем вызываете метод database.SubmitChanges(), который затем выполняет обновление для всей записи (или записей).

С точки зрения дизайна мне больше нравится первый вариант - когда свойство установлено, изменения происходят мгновенно, и он обрабатывается как любой другой объект. Но с технической точки зрения, я подозреваю, что производительность будет достигнута путем массового обновления.

Так какой метод мне выбрать - или есть другие варианты, которые я должен рассмотреть?

1 Ответ

1 голос
/ 19 сентября 2011

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

Обновление отдельных ячеек эквивалентно написанию SQL, например

-- new command
UPDATE [Table] SET [Column1] = 'Value1' WHERE [Id] = 1
GO
-- new command
UPDATE [Table] SET [Column2] = 'Value2' WHERE [Id] = 1
GO
-- new command
UPDATE [Table] SET [Column3] = 'Value3' WHERE [Id] = 1
GO

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

Предпочтительный метод - обновить все свойствасразу, а затем отправьте одну команду SQL.

UPDATE [Table] 
SET [Column1] = 'Value1', [Column2] = 'Value2', [Column3] = 'Value3'
WHERE [Id] = 1

Есть несколько шагов, и если вы думаете об этом физически и практически, все это должно иметь смысл.

Во-первых, LINQ-to-SQL извлекает всю строку, чтобы вы могли обновить свойства.Это необходимо сделать операциям «на ячейку» или «на строку», поэтому на это уходит одинаковое количество времени.

// the "Single" operator retrieves an entire row 
var TableName = scope.CellName.Single(v => v.ID == id);
var row = scope.MyTable.Single(v => v.Id == id); // more accurate description

-- sql looks something like this
SELECT TOP 1 * FROM [MyTable] WHERE [Id] = @id

Это включает

  • компиляцию запроса
  • открытие соединения / получение соединения из пула
  • отправка команды на сервер SQL
  • получение ответа от сервера SQL

Связь с другим сервером может занять от нескольких миллисекунд до многих секунд, в зависимости от расстояния, производительности, нагрузки на сервер и т. Д.

Затем вы обновляете свойство.

row.Column1 = data;

Это занимает простые циклы.Это неизмеримо малая составляющая общего времени работы.

И затем вы отправляете изменения.

scope.SubmitChanges();

-- sql looks like this
UPDATE [MyTable] SET /* set of columns to update */ WHERE [Id] = @id

Это снова включает несколько шагов

  • скомпилируйте запрос
  • , отправив команду на SQL Server
  • получив ответ от SQL Server

В обновлении ячеек по отдельности нет ничего «мгновенного» - ячейка будетобновляется одновременно с обновлением целой строки с использованием шаблона «на строку».Просто для обновления оставшихся ячеек потребуется больше .

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

...