Acabo de testar o novo OutputCache do ASP.Net MVC Preview 4. Notei que ele não tem uma forma de configurar uma dependência de Cache com SQL, nem mesmo via perfil de cache (Cache profile). De resto, funciona perfeitamente.

Para confirmar criei um projeto de testes e analisei um pouco mais a fundo. Dêem uma olhada como ficou meu Web.config abaixo.

Primeiro a seção de strings de conexão:

  <connectionStrings>
    <add name="Northwind2005ConnectionString" 
    connectionString="data source=gb2;Initial Catalog=Northwind2005;User ID=user;password=pwd" providerName="System.Data.SqlClient"/>
  </connectionStrings>

E agora seção de cache:

     <caching>
      <sqlCacheDependency enabled="true">
        <databases>
          <add name="Northwind2005" 
          connectionStringName="Northwind2005ConnectionString" 
          pollTime="10000"/>
        </databases>
      </sqlCacheDependency>
      <outputCacheSettings>
        <outputCacheProfiles>
          <add name="NorthwindCacheProfile" varyByParam="none" 
          sqlDependency="Northwind2005:Employees" 
          enabled="true" duration="600"/>
        </outputCacheProfiles>
      </outputCacheSettings>
    </caching>

Tudo configurado corretamente. Se você aplicar esse xml no seu web.config para trabalhar com web forms e aplicar um diretiva de @OutputCache na página vai funcionar.

No ASP.Net MVC funciona assim: você cria uma ação, e coloca o atributo de OutputCache. Para testar, criei um controlador de cache, e duas ações, a padrão, Index, e outra, para testar a interação com a dependência SQL, que usa a mesma View. Vejam como ficou:

namespace MvcApplication1.Controllers
{
    public class CacheTestController : Controller
    {
        [OutputCache(Duration=10)]
        public ActionResult Index()
        {
            ViewData["mensagem"] = "Última atualização às " 
            + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss");
            return View();
        }

        [OutputCache(CacheProfile = "NorthwindCacheProfile")]
        public ActionResult SQLCacheDep()
        {
            ViewData["mensagem"] = "(SQL Dep) Última atualização às " 
            + DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss");
            return View("Index");
        }
    }
}

A primeira funciona ok. A segunda resulta em um cache que só expira quando a duração é alcançada, ou seja, em 10 minutos (600 segundos). Abri um SQL Profiler e constatei: nada acontecendo lá, nenhuma conexão vindo da aplicação. Se fosse Web Forms estaria rodando a procedure “AspNet_SqlCachePollingStoredProcedure” para ver se alguma coisa mudou.

Para terminar, confirmei no código fonte do ASP.Net MVC a classe OutputCacheAttribute. Ela tem uma função chamada ApplyProfile, onde ela aplica os dados do Cache Profile, vejam só:

public void ApplyProfile(OutputCacheProfile profile) {
    Duration = profile.Duration;
    Location = profile.Location;
    NoStore = profile.NoStore;
    VaryByContentEncoding = profile.VaryByContentEncoding;
    VaryByCustom = profile.VaryByCustom;
    VaryByHeader = profile.VaryByHeader;
    VaryByParam = profile.VaryByParam;
}

Percebem como ela não aplica a propriedade “SqlDependency” do profile? Taí a explicação. O profile está sendo aplicado só com a duração configurada para expirar (propriedade duration), mais nada.

Imagino que a implementação deve sair no Preview 5, vamos ver.

Giovanni Bassi

Arquiteto e desenvolvedor, agilista, escalador, provocador. É fundador e CSA da Lambda3. Programa porque gosta. Acredita que pessoas autogerenciadas funcionam melhor e por acreditar que heterarquia é mais eficiente que hierarquia. Foi reconhecido Microsoft MVP há mais de dez anos, dos mais de vinte que atua no mercado. Já palestrou sobre .NET, Rust, microsserviços, JavaScript, TypeScript, Ruby, Node.js, Frontend e Backend, Agile, etc, no Brasil, e no exterior. Liderou grupos de usuários em assuntos como arquitetura de software, Docker, e .NET.