Почему хранимая процедура делает недействительной зависимость SQL Cache?

Через много часов я наконец понимаю, что правильно работаю с объектом Cache в своем приложении ASP.NET, но мои хранимые процедуры мешают ему работать правильно.

Эта хранимая процедура работает правильно:

CREATE PROCEDURE [dbo].[ListLanguages]
@Page INT = 1,
@ItemsPerPage INT = 10,
@OrderBy NVARCHAR (100) = 'ID',
@OrderDirection NVARCHAR(4) = 'DESC'
AS
BEGIN
    SELECT ID, [Name], Flag, IsDefault FROM dbo.Languages
END

Но это (то, что я хотел) не:

CREATE PROCEDURE [dbo].[ListLanguages]
@Page INT = 1,
@ItemsPerPage INT = 10,
@OrderBy NVARCHAR (100) = 'ID',
@OrderDirection NVARCHAR(4) = 'DESC',
@TotalRecords INT OUTPUT
AS
BEGIN
    SET @TotalRecords = 10

EXEC('SELECT ID, Name, Flag, IsDefault FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY ' + @OrderBy + ' ' + @OrderDirection + ') as Row, ID, Name, Flag, IsDefault
    FROM dbo.Languages) results
    WHERE Row BETWEEN ((' + @Page + '-1)*' + @ItemsPerPage + '+1) AND (' + @Page + '*' + @ItemsPerPage + ')')
END

Я дал параметру @TotalRecords значение 10, чтобы вы могли быть уверены, что проблема не в функции COUNT(*), которая, как я знаю, не поддерживается должным образом.

Кроме того, когда я запускаю его из SQL Server Management Studio, он делает именно то, что должен делать. В приложении ASP.NET результаты извлекаются корректно, только кеш как-то не может работать!

Можете ли вы помочь?

Возможно подсказка

Я полагаю, что причина, по которой свойство зависимостей HasChanged связано с тем, что столбец Row, сгенерированный из ROW_NUMBER, является только временным, и поэтому SQL SERVER не может сказать, изменились ли результаты или нет. Вот почему HasChanged всегда имеет значение true.

Кто-нибудь знает, как разбить на страницы результаты из SQL SERVER без использования функций COUNT или ROW_NUMBER?

3 ответа

Решение

Зависимость кэша SQL для.NET 3.5 работает только для простых запросов. Может быть.NET 4 меня удивит.

Недостаточно размера кэша.

1 - Можете ли вы скопировать и вставить код, который вы фактически используете для кэширования результатов этого спрока? 2 - Вы пробовали sproc, где вы используете прямой запрос вместо EXEC-строки?

Да #2 означает, что вы не можете изменить структуру запроса на лету:-), но если вы не вычисляете свои собственные критерии кэширования в #1, это правило кэширования, которое вы должны соблюдать в целом. Ни один механизм кеширования никогда не сможет проанализировать строку из EXEC от вас.

ВЫПОЛНЕНИЕ строки в sproc приводит к тому, что при каждом запуске, даже для самого SQL Server, происходит бросок монеты. Это также оставляет вас открытыми для атак с помощью внедрения скриптов, так как ваш запрос все еще состоит из строк во время выполнения - это ничем не отличается от составления всей строки в C# и передачи ее в sproc для "просто EXEC, что находится внутри"

Другие вопросы по тегам