Cache и SqlCacheDependency (ASP.NET MVC) - PullRequest
0 голосов
/ 09 октября 2009

Нам нужно вернуть подмножество записей, и для этого мы используем следующую команду:

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 ]

1 голос
/ 22 марта 2010

Я не эксперт по SqlCacheDependency, на самом деле, я нашел этот вопрос, когда искал ответы на свои вопросы! Однако я считаю, что причина, по которой ваша SqlCacheDependency не работает, заключается в том, что ваш SQL содержит вложенный подзапрос.

Посмотрите документацию, в которой перечислено, что вы можете / не можете использовать в своем SQL: Создание запроса для уведомлений

".... Оператор не должен содержать подзапросов, внешних объединений или самостоятельных объединений ....."

Я также нашел некоторую неоценимую информацию по устранению неполадок от парня из Redgate: Использование и мониторинг уведомлений о запросах SQL 2005 , которые помогли мне решить мою собственную проблему: используя Sql Profiler для отслеживания событий QN, которые он предлагает я смог определить, что мое соединение неправильно, используя опцию «SET ARITHABORT OFF», что привело к сбою моих уведомлений.

1 голос
/ 11 декабря 2014

Столкнувшись с той же проблемой и найдя те же ответы в Интернете без какой-либо помощи, я повторно изучил ответ недействительной подписки xml от профилировщика.

Я нашел пример на сайте поддержки msdn с немного другим порядком кода. Когда я попробовал это, я понял проблему - не открывайте свой объект соединения, пока вы не создадите объект команды и объект зависимости кэша. Вот порядок, которому вы должны следовать, и все будет хорошо:

  1. Обязательно включите уведомления (SqlCahceDependencyAdmin) и запустите SqlDependency.Start first
  2. Создать объект подключения
  3. Создайте объект команды и назначьте текст команды, тип и объект соединения (любая комбинация конструкторов, свойства настроек или использование CreateCommand).
  4. Создание объекта зависимости sql-кэша
  5. Открыть объект подключения
  6. Выполнить запрос
  7. Добавление элемента в кэш с использованием зависимости.

Если вы следуете этому порядку и соблюдаете все другие требования в своем утверждении select, у вас нет проблем с разрешениями, это будет работать!

Я полагаю, что проблема связана с тем, как .NET Framework управляет соединением, в частности с настройками. Я попытался переопределить это в моем тесте команды sql, но он никогда не работал. Это только предположение - я знаю, что изменение порядка немедленно решило проблему.

Я смог собрать его из следующих сообщений в сообщения MSDN.

Эта публикация была одной из наиболее распространенных причин недействительной подписки и показывает, как клиент .Net устанавливает свойства, которые отличаются от того, что требуется для уведомления.

https://social.msdn.microsoft.com/Forums/en-US/cf3853f3-0ea1-41b9-987e-9922e5766066/changing-default-set-options-forced-by-net?forum=adodotnetdataproviders

Тогда это сообщение было от пользователя, который, как и я, сократил свой код до самого простого формата. Мой оригинальный шаблон кода был похож на его.

https://social.technet.microsoft.com/Forums/windows/en-US/5a29d49b-8c2c-4fe8-b8de-d632a3f60f68/subscriptions-always-invalid-usual-suspects-checked-no-joy?forum=sqlservicebroker

Тогда я нашел этот пост, тоже очень простое решение проблемы, только его проблема была простой - требовалось имя из 2 частей для таблиц. В его случае предложение решило проблему. Посмотрев его код, я заметил, что основным отличием было ожидание открытия объекта подключения, пока ПОСЛЕ команды объекта И объект зависимости не были созданы. Мое единственное предположение скрыто (я еще не запустил рефлектор для проверки, поэтому только предположение), объект Соединения открывается по-другому, или порядок событий и команды происходят по-разному из-за этой ассоциации.

https://social.msdn.microsoft.com/Forums/sqlserver/en-US/bc9ca094-a989-4403-82c6-7f608ed462ce/sql-server-not-creating-subscription-for-simple-select-query-when-using-sqlcachedependency?forum=sqlservicebroker

Надеюсь, это поможет кому-то еще в аналогичной проблеме.

1 голос
/ 09 октября 2009

Просто предположение, но может ли это быть из-за того, что в вашем выражении 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
...