Cache e SqlCacheDependency (ASP.NET MVC)
-
20-09-2019 - |
Pergunta
Precisamos voltar para o subconjunto de registros e para isso usamos o seguinte comando:
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))
Eu definido um SqlCacheDependency declarado assim:
SqlCacheDependency cacheDependency = new SqlCacheDependency(command);
Mas, imediatamente depois de executar o comando.ExecuteReader() instrução, o hasChanged da base de dados de propriedade da SqlCacheDependency objeto se torna verdadeiro, apesar de não me alterar o resultado da consulta, de forma alguma!E, devido a isso, o resultado desta consulta não é mantido em cache.
HttpRuntime.Cache.Insert( cacheKey, list, cacheDependency, Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(AppConfiguration.CacheExpiration.VeryLowActivity));
É porque o comando 2 instruções SELECT?É ROW_NUMBER()?Se sim, existe alguma outra maneira para paginar resultados?
Por favor, ajuda!Depois de muitas horas, um pouco será muito apreciada!Obrigado
Solução
Chegando ao mesmo problema e encontrando as mesmas respostas on -line sem ajuda, eu estava pesquisando a resposta de subcriagem inválida XML do Profiler.
Encontrei um exemplo no site de suporte do MSDN que tinha uma ordem de código ligeiramente diferente. Quando tentei, percebi o problema - não abra seu objeto de conexão até que você criasse o objeto de comando e o objeto de dependência do cache. Aqui está a ordem que você deve seguir e tudo será bom:
- Certifique -se de ativar as notificações (SQLCAHDEEPENDENCENDMIN) e executar o sqldependency.start primeiro
- Crie o objeto de conexão
- Crie o objeto de comando e atribua texto, tipo e objeto de conexão de comando (qualquer combinação de construtores, configurações de propriedades ou usando o createCommand).
- Crie o objeto de dependência do cache SQL
- Abra o objeto de conexão
- Execute a consulta
- Adicione o item ao cache usando dependência.
Se você seguir este pedido e seguir todos os outros requisitos em sua instrução SELECT, não tenha problemas de permissões, isso funcionará!
Acredito que o problema tem a ver com a forma como a estrutura .NET gerencia a conexão, especificamente quais configurações estão definidas. Tentei substituir isso no meu teste de comando SQL, mas nunca funcionou. Isso é apenas um palpite - o que eu sei é alterar o pedido imediatamente resolveu o problema.
Consegui reuni -lo desde as postagens seguintes para o MSDN.
Esta postagem foi uma das causas mais comuns da assinatura inválida e mostra como o cliente .NET define as propriedades que contrastam com o que a notificação exige.
Então este post foi de um usuário que, como eu, havia reduzido seu código para o formato mais simples. Meu padrão de código original era semelhante ao dele.
Então eu encontrei este post, também uma redução muito simples do problema, apenas o dele era um problema simples - precisando de duas peças para tabelas. No caso dele, a sugestão resolveu o problema. Depois de olhar para o código dele, notei que a principal diferença estava esperando para abrir o objeto de conexão até que o objeto de comando e o objeto de dependência fossem criados. Minha única suposição está sob o capô (ainda não iniciei o refletor para verificar, portanto, apenas uma suposição) o objeto de conexão é aberto de maneira diferente, ou a ordem de eventos e o comando acontece de maneira diferente, por causa dessa associação.
Espero que isso ajude outra pessoa em uma questão semelhante.
Outras dicas
Apenas um palpite, mas poderia ser porque o seu SELECT
declaração não tem um ORDER BY
cláusula?
Se você não especificar uma ordem explícita, é possível que a consulta retorne os resultados em qualquer ordem cada vez que for executada. Talvez isso esteja causando o SqlCacheDependency
Objeta -se a pensar que os resultados mudaram.
Tente adicionar um ORDER BY
cláusula:
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
eu não sou nenhum especialista em SqlCacheDependency, na verdade, eu achei essa pergunta, enquanto a procura de respostas para os meus próprios problemas com ele!No entanto, eu acredito que a razão do seu SqlCacheDependency não está funcionando é porque o SQL contém um sub aninhada consulta.
Dê uma olhada na documentação que lista o que você pode/não pode usar no seu SQL: Criar uma Consulta de Notificação de
"....A instrução não deve conter subconsultas, associações externas, ou self-joins....."
Eu também achei alguns inestimável informações sobre resolução de problemas de um cara em Redgate aqui: Utilização e Acompanhamento de Notificação de Consulta SQL 2005 que me ajudou a resolver meu próprio problema:Utilizando o Sql Profiler para rastrear a QN eventos que ele sugere, eu era capaz de manchar a minha ligação foi incorretamente usando o 'SET ARITHABORT OFF' opção, fazendo com que o meu notificações de falha.