Linq to SQL, обновить много строк - PullRequest
2 голосов
/ 16 марта 2012

Мне нужно обновить строку аварий с помощью Linq для SQL, которая может содержать более 100000 строк.

Это означает, что простое обновление, такое как:

foreach (var alarm in Alarms)
{
    alarm.Alarm_Ack_UTC = DateTime.UtcNow;
}

SubmitChanges();

, дает мнеSQL-запрос

SELECT [t0].[Alarm_ID], [t0].[Alarm_Application_Number], [t0].[Alarm_Ack_UTC], [t0].[Alarm_DateTime_UTC], [t0].[Alarm_Message_Number], [t0].[Username], [t0].[Runtime_Message], [t0].[Alarm_Application_Name], [t0].[Alarm_Application_Computer], [t0].[Alarm_GUID], [t0].[Alarm_Comments]
FROM [Alarms] AS [t0]
GO

-- Region Parameters
DECLARE @p0 Int = 1
DECLARE @p1 DateTime = '2012-03-16 11:56:25.850'
-- EndRegion
UPDATE [Alarms]
SET [Alarm_Ack_UTC] = @p1
WHERE [Alarm_ID] = @p0
GO

-- Region Parameters
DECLARE @p0 Int = 2
DECLARE @p1 DateTime = '2012-03-16 11:56:25.851'
-- EndRegion
UPDATE [Alarms]
SET [Alarm_Ack_UTC] = @p1
WHERE [Alarm_ID] = @p0
GO

-- Region Parameters
DECLARE @p0 Int = 3
DECLARE @p1 DateTime = '2012-03-16 11:56:25.851'
-- EndRegion
UPDATE [Alarms]
SET [Alarm_Ack_UTC] = @p1
WHERE [Alarm_ID] = @p0
GO

Повторяется 100000 раз, что действительно медленно, неэффективно и неоптимизировано.Реальный запрос более сложный и обновляет больше данных, использует .Where (a => a.Time! = Null) и другие вещи.

Но только для улучшения запроса выше, который можно заменить наочень эффективный SQL-запрос:

UPDATE [Alarms]
SET Alarm_Ack_UTC = GETUTCDATE()
GO

Как этого добиться с помощью Linq to SQL?Или это невозможно?

Ответы [ 3 ]

3 голосов
/ 16 марта 2012

Вы не можете сделать это с LINQ to SQL (или любым другим O / RM). Они всегда будут извлекать объект из базы данных, который вы хотите изменить, и будут иметь единый оператор обновления для этой сущности. Если вы измените 10000 объектов, у вас будет не менее 10 000 операторов обновления.

Если это слишком медленно, переключитесь на хранимую процедуру или инструкцию SQL в этом случае.

2 голосов
/ 16 марта 2012

Я бы выбрал для написания хранимой процедуры.

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

2 голосов
/ 16 марта 2012

Если вам нужно запустить определенный оптимизированный SQL, такой как (через Linq to SQL), вам нужно будет использовать ExecuteQuery . Итак, используя ваш пример, вы можете сделать:

  db.ExecuteQuery<Alarm>("UPDATE [Alarms] SET Alarm_Ack_UTC = GETUTCDATE()");

Если вы хотите более оптимизированный способ обновления нескольких строк с разными значениями, вам следует подумать об использовании SqlBulkCopy , который специфичен для SQL-сервера, но не Linq to SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...