Cache и SqlCacheDependency (ASP.NET MVC)
Нам нужно вернуть подмножество записей, и для этого мы используем следующую команду:
using (SqlCommand command = new SqlCommand(
"SELECT ID, Name, Flag, IsDefault FROM (SELECT ROW_NUMBER() OVER (ORDER BY @OrderBy DESC) as Row, ID, Name, Flag, IsDefault FROM dbo.Languages) results WHERE Row BETWEEN ((@Page - 1) * @ItemsPerPage + 1) AND (@Page * @ItemsPerPage)",
connection))
Я установил SqlCacheDependency, объявленный так:
SqlCacheDependency cacheDependency = new SqlCacheDependency(command);
Но сразу же после запуска команды command.ExecuteReader() базовое свойство hasChanged объекта SqlCacheDependency становится истинным, хотя я никоим образом не изменил результат запроса! И из-за этого результат этого запроса не сохраняется в кеше.
HttpRuntime.Cache.Insert( cacheKey, list, cacheDependency, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(AppConfiguration.CacheExpiration.VeryLowActivity));
Это потому, что команда имеет 2 оператора SELECT? Это ROW_NUMBER()? Если да, есть ли другой способ разбить результаты на страницы?
Пожалуйста помоги! После слишком много часов, немного будет высоко ценится! Спасибо
3 ответа
Столкнувшись с той же проблемой и найдя те же ответы в Интернете без какой-либо помощи, я повторно изучил ответ недействительной подписки xml от профилировщика.
Я нашел пример на сайте поддержки msdn, у которого был немного другой порядок кода. Когда я попробовал это, я понял проблему - не открывайте свой объект соединения, пока вы не создадите объект команды и объект зависимости кэша. Вот порядок, которому вы должны следовать, и все будет хорошо:
- Обязательно включите уведомления (SqlCahceDependencyAdmin) и сначала запустите SqlDependency.Start.
- Создать объект подключения
- Создайте объект команды и назначьте текст команды, тип и объект подключения (любую комбинацию конструкторов, настройки свойств или использование CreateCommand).
- Создать объект зависимости sql cache
- Откройте объект подключения
- Выполнить запрос
- Добавить элемент в кеш, используя зависимости.
Если вы следуете этому порядку и соблюдаете все другие требования в своем утверждении select, у вас нет проблем с разрешениями, это будет работать!
Я считаю, что проблема связана с тем, как.NET Framework управляет соединением, в частности, какие настройки установлены. Я попытался переопределить это в моем тесте команды sql, но он никогда не работал. Это всего лишь предположение - я знаю, что изменение порядка сразу решило проблему.
Я был в состоянии соединить это от следующих до сообщений MSDN.
Эта публикация была одной из наиболее распространенных причин недействительной подписки и показывает, как клиент.Net устанавливает свойства, которые отличаются от того, что требуется для уведомления.
Тогда этот пост был от пользователя, который, как и я, сократил свой код до самого простого формата. Мой оригинальный шаблон кода был похож на его.
Затем я обнаружил, что этот пост - тоже очень простое решение проблемы, только его проблема была простой - требовалось имя из двух частей для таблиц. В его случае предложение решило проблему. Посмотрев его код, я заметил, что главное отличие заключается в ожидании открытия объекта подключения, пока ПОСЛЕ команды объекта И объект зависимости не были созданы. Мое единственное предположение скрыто (я еще не запускал рефлектор для проверки, поэтому только предположение), что объект Connection открывается по-другому, или порядок событий и команды происходят по-разному из-за этой ассоциации.
Я надеюсь, что это помогает кому-то еще в аналогичной проблеме.
Просто предположение, но может ли это быть потому, что ваш SELECT
заявление не имеет ORDER BY
статья?
Если вы не укажете явное упорядочение, запрос сможет возвращать результаты в любом порядке при каждом запуске. Может быть, это вызывает SqlCacheDependency
объект думать, что результаты изменились.
Попробуйте добавить ORDER BY
пункт:
SELECT ID, Name, Flag, IsDefault
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY @OrderBy DESC) AS Row,
ID, Name, Flag, IsDefault
FROM dbo.Languages
) AS results
WHERE Row BETWEEN ((@Page - 1) * @ItemsPerPage + 1) AND (@Page * @ItemsPerPage)
ORDER BY Row
Я не эксперт по SqlCacheDependency, на самом деле, я нашел этот вопрос, когда искал ответы на свои вопросы! Однако я полагаю, что причина, по которой ваша SqlCacheDependency не работает, заключается в том, что ваш SQL содержит вложенный подзапрос.
Посмотрите на документацию, в которой перечислено, что вы можете / не можете использовать в своем SQL: Создание запроса на уведомление
".... Оператор не должен содержать подзапросов, внешних объединений или самостоятельных объединений....."
Я также нашел некоторую бесценную информацию по устранению неполадок от парня из Redgate здесь: Использование и мониторинг уведомлений о запросах SQL 2005, которые помогли мне решить мою собственную проблему: с помощью Sql Profiler для отслеживания событий QN, которые он предлагает, я смог определить, что мое соединение было неправильно используя опцию "SET ARITHABORT OFF", чтобы мои уведомления перестали работать.