Как сделать OutputCache с SqlDependency зависимым от строки в базе данных для каждого запроса? - PullRequest
8 голосов
/ 06 марта 2012

У меня проблема.Не удается найти, как сделать OutputCache SQLDependency зависимым от одной строки из таблицы базы данных.Например, у меня есть контроллер с одним параметром.

ActionResult Index(int? id)

И для каждого запроса с тем же идентификатором мне нужно проверить таблицу базы данных table1 (id int, last_updated datetime).Если строка с id = id и last_updated не изменилась.

Я использую SQL Server 2005 или выше.

Какую стратегию мне следует использовать?

Я пытался использовать:

[OutputCache(Duration = int.MaxValue, VaryByParam = "id", 
    SqlDependency = "DatabaseName:table1")]

, но это работает для изменений всей таблицы.

Ответы [ 2 ]

7 голосов
/ 03 октября 2013

Чтобы избежать попадания в базу данных для каждого запроса веб-страницы (обычно это дорогостоящая операция), можно использовать объектное кэширование (представленное в .NET 4.0).Это приведет к быстрому обслуживанию веб-страниц, потому что все будет обрабатываться непосредственно из памяти.Операции с базой данных будут выполняться только в том случае, если данные действительно изменились или если кэш был удален из памяти из-за ограничений ресурсов или настроек CacheItemPolicy.

Практическая стратегия, используемая в этом случае, будет следующей.

Шаг-1.В методе вашей модели, где данные для строки "id" изменяются / добавляются / удаляются, завершите эту операцию базы данных и затем:

Шаг-2.Извлекайте объект из кэша всякий раз, когда это возможно, обновляя из базы данных только при необходимости:

  • Из вашего метода действия Controller вызовите метод Model, который возвращает объект, идентифицированный параметром "id";
  • В вашем методе Model проверьте кеш для этого идентификатора.Если значение равно null, извлеките данные из базы данных и создайте объект, как обычно, а затем сохраните весь объект в кеше;
  • Из метода Model верните содержимое кеша (т. Е.ваш конкретный объект для этого идентификатора) обратно в вызывающий метод действия Controller, а затем позвольте методу действия заполнить и обслуживать представление как обычно.

(класс MemoryCache являетсяконкретная реализация класса ObjectCache).

При таком подходе нет необходимости вообще использовать OutputCache для метода Controller, а все решения по кэшированию данных будут полностью инкапсулированы в модели.Мы бы получили более четкое разделение интересов;гораздо более высокая эффективность, лучшее время отклика и улучшенная масштабируемость;и уменьшенная зависимость от дорогостоящих операций с базой данных.

3 голосов
/ 03 октября 2013
[OutputCache (Duration=int.MaxValue VaryByParam="None" VaryByCustom="SqlRow")]

В вашем global.asax вы должны сделать следующее.

Public override string GetVaryByCustomString(HttpContext context, string arg) 
{ 
  if(arg.ToLower() == "sqlrow") 
  { 
     using(SqlConnection conn = new SqlConnection(... ) )
     {
         conn.Open();
         var cmd = conn.CreateCommand();
         var id = context.QueryString["id"];
         cmd.CommandText = "SELECT LastModifiedTime FROM Table WHERE ID = @id";
         cmd.Parameters.Add( "id", id );
         return cmd.ExecuteScalar();
     }
  } 
  return base.GetVaryByCustomString(context, arg); 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...