Обновления LINQ to SQL - PullRequest
0 голосов
/ 23 мая 2009

Есть ли у кого-нибудь представление о том, как выполнить следующий оператор с помощью LINQ?

UPDATE FileEntity SET DateDeleted = GETDATE() WHERE ID IN (1,2,3)

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

foreach (var file in db.FileEntities.Where(x => ids.Contains(x.ID)))
{
    file.DateDeleted = DateTime.Now;
}
db.SubmitChanges();

Проблема с вышеприведенным кодом, за исключением значительных издержек, состоит в том, что у каждого объекта есть поле данных, которое может быть довольно большим, поэтому при большом обновлении большое количество данных проходит через соединение с базой данных без особой причины. (Решение LINQ заключается в отсрочке загрузки свойства Data, но в этом нет необходимости, если есть какой-то способ просто обновить поле с помощью LINQ to SQL).

Я думаю, что какой-то провайдер выражений запросов может привести к приведенному выше T-SQL ...

Ответы [ 2 ]

2 голосов
/ 23 мая 2009

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

Если вы действительно заботитесь об этой оптимизации, используйте хранимую процедуру или рукописный оператор SQL. Если вам нужен код сжатия, вы можете использовать следующее.

db.FileEntities.
    Where(x => ids.Contains(x.ID)).
    Select(x => x.DateDeleted = DateTime.Now; return x; );

db.SubmitChanges();

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

0 голосов
/ 23 мая 2009

LINQ to SQL - это ORM, как и любой другой, и как таковой, он не был предназначен для обработки массовых обновлений / вставок / удалений. Общая идея с L2S, EF, NHibernate, LLBLGen и остальным состоит в том, чтобы обрабатывать сопоставление реляционных данных с вашими объектными графами, избавляя вас от необходимости управлять большой библиотекой хранимых процессов, что, в конечном счете, ограничивает вашу гибкость и адаптивность.

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

Это лучшее решение для рассматриваемой проблемы, которая является массовым обновлением. Как и в случае с отчетами, графы объектов и объектно-реляционное отображение не являются лучшим решением для массовых процессов.

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