Используя EF4, как я могу отследить, сколько раз запись является частью набора результатов Skip (). Take () - PullRequest
4 голосов
/ 05 мая 2011

Итак, используя EF4, я запускаю поисковый запрос, который заканчивается этой общей функцией:

query = query.Skip(5).Take(10);

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

Какой самый эффективный способ сделать это? В общем, я просто собираюсь посмотреть на набор результатов, получить список идентификаторов и затем снова попасть в базу данных, используя ADO.NET, чтобы сделать что-то вроде:

UPDATE TableName SET ImpressionCount = ImpressionCount + 1 WHERE Id IN (1,2,3,4,5,6,7,8,9,10)

Кажется достаточно простым, просто интересно, есть ли более .NET 4 / Linq-иш способ сделать это, о котором я не думаю. Тот, который не связан с другим попаданием в базу данных, тоже подойдет. :)

РЕДАКТИРОВАТЬ : Итак, я склоняюсь к ответу IAbstract в качестве ответа, так как не кажется, что для этого есть «встроенный» способ. Я не думал, что было, но это никогда не повредит спросить. Тем не менее, единственный другой вопрос, который я хочу отбросить, это: можно ли написать SQL-триггер, который мог бы работать только с этим конкретным запросом? Я не хочу, чтобы ImpressionCount обновлялся в КАЖДОМ утверждении выбора для записи (например, когда кто-то просматривает страницу сведений, это не впечатление - если администратор редактирует запись в бэкэнде, это не впечатление) ... можно использовать LINQ или нет?

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

Ответы [ 2 ]

5 голосов
/ 05 мая 2011

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

1 голос
/ 05 мая 2011

Технически можно использовать .Select - для изменения каждого элемента в возвращаемом результате , но это не идиоматический C # / linq, поэтому лучше использовать цикл foreach.

Пример:

var query = query.ToList().Select(x => { x.ImpressionCount++; return x; });

Как сказал IAbstract, будьте осторожны с проблемами производительности.Используя приведенный выше пример, или foreach выполнит 10 обновлений.Ваше одно заявление об обновлении лучше.

Я знаю, что у Linq2NHibernate такая же проблема - попытка придерживаться Linq просто бесполезна для обновлений (вот почему она называется «языковой интегрированный запрос »).);

Редактировать :

На самом деле, вероятно, нет причин, по которым EF4 или NHibernate не могли бы проанализировать выражение выбора, понять, что это обновление, и перевести его в обновление.Заявление выполнить его, но, конечно, ни одна структура не будет делать это.Если бы это могло произойти, вы бы хотели, чтобы новый .Update() метод расширения для IQueryable<T> явно указывал, что вы изменяете данные.Использование .Select() для этого является грязным хаком.

... что означает, что нет никакой причины, по которой вы не можете написать свой собственный метод расширения .Update(x => x.ImpressionCount++) для IQueryable<T>, который выводит необходимый вам SQL и вызывает ExecuteStoreCommand , но было бы много работы.

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