ASP.NET MVC ‹OutputCache› SqlDependency (CommandNotification?) с запросами LINQ

Я использую запросы LINQ в своем приложении ASP.NET MVC и хочу использовать OutputCache в некоторых своих действиях.

Я слышал, что это должно быть возможно с помощью CommandNotifications. Но похоже, что они подходят только для самостоятельно созданных SQLCommands, или я ошибаюсь?

Могу ли я вручную указать SQL-серверу отправлять уведомления SQLDependency при изменении определенных таблиц? И если да, то как их прикрепить к OutputCache?

Еще один побочный вопрос: можете ли вы сделать это и с представлениями строгого типа?

Заранее спасибо...


person sinni800    schedule 04.05.2010    source источник


Ответы (2)


Вы можете попробовать проект LinqToCache. Он делает именно то, что вы просите, подключает SqlDependency к любому запросу LINQ, если запрос, отправленный на SQL Server, соответствует Ограничения уведомлений о запросах. Для Linq-to-SQL это в основном состоит из указания полного двухчастного имени для таблиц в конструкторе моделей (т. е. dbo.Table, а не только Table). К сожалению, для Linq-to-EF способ форматирования запроса, выбранный EF, несовместим с ограничениями QN.

person Remus Rusanu    schedule 02.08.2010

Но похоже, что они подходят только для самостоятельно созданных SQLCommands, или я ошибаюсь?

Я бы сказал, что они полезны только для "самостоятельно созданных" команд, потому что это единственные, о которых вы можете знать заранее. Если вы хотите создать уведомление для определенного запроса LINQ, тогда вы просто вызовете метод в коде вместе с запросом.

Могу ли я вручную указать SQL-серверу отправлять уведомления SQLDependency при изменении определенных таблиц?

Конечно. Сделать уведомление о:

SELECT * FROM TABLENAME;

И если да, то как их прикрепить к OutputCache?

Создайте команду, создайте зависимость кеша и ссылайтесь на нее при добавлении в кеш. Инициализируйте уведомления о зависимостях в global.asax.cs как обычно.

Можете ли вы сделать это и с представлениями строгого типа?

Не имеет смысла. В MVC вы не должны выполнять доступ к данным в представлении.

person Craig Stuntz    schedule 04.05.2010
comment
› Вы бы просто вызвали метод в коде вместе с запросом... Какой метод? SqlDependency.Start(connectionString) может быть? › Сделать команду New SqlCommand с SELECT * from TABLENAME? › создайте зависимость кеша и ссылайтесь на нее при добавлении в кеш... Я этого не понял.. извините... › Инициализируйте уведомления о зависимости в global.asax.cs, как обычно. Я где-то это читал... Я получил оттуда пример кода... С пользовательским событием OnChange. Что это делает? И как это помогает с атрибутом OutputCache? Я совсем запутался в этой теме... - person sinni800; 04.05.2010
comment
Мое первое замечание: вам не нужны уведомления для пользовательских запросов. Вы можете просто вызвать все, что хотите, прямо здесь, вместо того, чтобы ждать уведомления. Уведомления нужны, когда вы хотите знать, когда кто-то еще изменил данные. Да, Start. Что касается того, как добавить зависимость от кеша, какая часть документов MSDN по этому поводу вам не ясна? - person Craig Stuntz; 04.05.2010
comment
Я чувствую, что есть так много способов сделать это, и я не знаю, какой из них мне подходит. Мне не нужны уведомления для пользовательских запросов? Что тогда? У меня есть веб-сайт с содержанием, которое может часто меняться всеми. Что-то вроде форума. Так что я думаю, что кто-то еще применяется здесь. Также я не знаю, где искать в документах MSDN. - person sinni800; 04.05.2010
comment
Если единственным приложением, которое когда-либо будет изменять базу данных, является ваше приложение, вам не нужны уведомления о запросах. Вам нужен (1) CQRS как общий шаблон приложения и (2) шаблон репозитория для уведомлений, когда они вам действительно нужны. Сделать кэш недействительным сложно; нет ни одного класса, который решит эти проблемы за вас. Что касается фактического использования SqlCacheDependency, то есть пример на обзорной странице для SqlCacheDependency msdn.microsoft.com/en-us/library/. Просто представьте, что это где-то кроме Page_Load. - person Craig Stuntz; 04.05.2010
comment
Благодаря вам я стал ближе к пониманию того, что происходит. Итак, мне нужна команда для SQLDependency... Я мог бы заменить эти важные команды LINQ реальными командами SQL и создать для них SQLDependencies. Я прав с этим? Или я мог бы использовать LinqDataContext.GetCommand, чтобы получить команду TSQL, которая соответствует выполненному LINQ... Когда я создаю эти объекты SQLDependency с командами и использую SQLDependency.Start, вызовет ли он CommandNotification, как в ‹OutputCache SqlDependency:=CommandNotification )› (мой атрибут действия, параметры опущены) тогда? - person sinni800; 04.05.2010
comment
Нет, было бы неправильно заменить LINQ на SQL. Пожалуйста, отнеситесь к этому правильно: вам действительно нужно потратить некоторое время на изучение того, как уведомления о запросах работают внутри SQL Server, прежде чем вы попытаетесь реализовать их в своем приложении. Здесь дьявол кроется в деталях. Никто не может объяснить это в одном ответе на переполнение стека. Это сложная тема, и она не является волшебным средством для решения проблем с производительностью. - person Craig Stuntz; 04.05.2010
comment
Пока я знаю, что есть сервис-брокеры, которые обращаются к приложению ASP.NET. Приложение ASP.NET, похоже, помещает эти обратные вызовы в файл cookie, который вы можете получить с помощью удаленного взаимодействия. Я думал, что это можно реализовать так же просто, как и без использования LINQ. - person sinni800; 05.05.2010
comment
Если вы считаете, что зависимости кэша SQL всегда просты, значит, вы не до конца поняли проблему. Правильная политика кэширования всегда сложна. Зависимости SQL добавляют дополнительный уровень сложности. Не позволяйте тому факту, что легко вставить директиву на страницу ASPX, ввести вас в заблуждение, думая, что кэширование — это просто! - person Craig Stuntz; 05.05.2010
comment
Уф. Мое приложение даже не было бы таким большим... Но я попробую просто прочитать его... Я думал, что Framework автоматически определяет, где вы делаете SQL, и, в зависимости от этого, настраивает механизмы с SQL Server. В моем случае был бы только ОДИН запрос (выбрать * из таблицы), который нужно было бы кэшировать, поэтому я подумал, что это будет легко реализовать. Просто аннулируйте кеш HTML, когда SQL Server обнаружит, что таблица изменилась. Ничего больше. - person sinni800; 08.05.2010
comment
То, о чем вы просите, не так просто, как вы думаете. Остерегайтесь преждевременной оптимизации. Создайте свое приложение, заставьте его работать, а затем подумайте о кэшировании, когда вы профилируете его и найдете самые медленные части. - person Craig Stuntz; 10.05.2010