ASP.Net MVC Управляемое базой данных меню с кэшированием

Я пытаюсь создать меню для моего сайта. Это должно соответствовать следующим требованиям

  • он должен управляться базой данных, извлекая данные из БД для построения структуры меню
  • данные, извлекаемые из БД, должны быть кэшированы - я не хочу нажимать на БД для каждого запроса страницы

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

У меня есть ProductMenuAttribute, который извлекает данные из БД и сохраняет их в ViewData:

public class ProductMenuAttribute: FilterAttribute, IActionFilter
{
    #region IActionFilter Members

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        if (filterContext != null)
        {
            var context = filterContext.Result as ViewResult;
            if (context != null)
            {
                ProductsRepository repository = new ProductsRepository(Properties.Settings.Default.SqlConnectionString);

                context.ViewData.Add("ProductsList", repository.GetAllProductRanges());
            }
        }
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {

    }

    #endregion
}

В моем Site.master я извлекаю данные из ViewData и использую их для отображения моего меню. Это небольшой фрагмент моего неупорядоченного списка меню, стилизованный под CSS. Вот код:

            <li>
                <%= Html.ActionLink("Products", "Index", "Products")%>

                <%  IQueryable<ProductRange> productRanges = ViewData["ProductsList"] as IQueryable<ProductRange>; %>

                    <% if (productRanges != null)
                       { %>

                    <ul>
                        <% foreach (ProductRange range in productRanges) 
                           { %>   
                            <li><%= Html.ActionLink(range.Name, "RangeDetails", "Products", new { id = range.ID }, null)%></li>
                        <% } %>
                    </ul>

                    <% } %>
            </li>

Затем я украшаю каждый контроллер атрибутом [ProductMenu] следующим образом:

[ProductMenu]
public class HomeController : BaseController
{
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

Теперь всякий раз, когда выполняется какое-либо действие на моем контроллере, вызывается метод OnActionExecuted в классе ProductMenuAttribute, который устанавливает ViewData, который в конечном итоге будет использоваться на моем Site.Master для создания моего меню из БД, и в этот раз Я называю любое из действий.

Проблема сейчас в том, как добавить кеширование в этот сценарий? Я понятия не имею, с чего начать, и чувствую, что решение, которое я имею, не кешируется.

3 ответа

Решение

Я думаю, что мне действительно нужно использовать вспомогательное расширение Html.RenderAction() из проекта MVC Futures.

Идея состоит в том, чтобы использовать вышеупомянутое для вызова действия на контроллере, который сгенерирует структуру меню HTML, извлекая данные из БД. Затем я также использую простое кэширование вывода для кэширования данных на несколько минут.

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

РЕДАКТИРОВАТЬ: Фил Хаак недавно написал об этом в блоге - Html.RenderAction и Html.Action. Отличное сообщение в блоге, охватывающее все мои точные потребности, с объяснением всех проблем.

Чтобы кэширование работало правильно, мне нужно поставить Html.RenderAction() вызов внутри ViewUserControl с установленной директивой OutputCaching следующим образом:

<@ OutputCache Duration="100" VaryByParam="None" %>

Я тогда называю выше с Html.RenderPartial()и вуаля, все работает!

Вы можете изменить свой репозиторий так, чтобы он учитывал кеш: см. Два вопроса: кэшированный репозиторий и http кеш.

Я сделал это с помощью блока кэширования Enterprise Library. Вы проверяете кэшированные данные, если нет кэшированных данных, вы создаете HTML-строку из данных в вашей базе данных и помещаете ее в кеш, чтобы позже при поиске кэшированных данных вы могли просто вывести простую строку:D

Просто упомянуть, что код для этого был в статическом классе. Я приведу пример, но я переписываю это приложение в MVC2 с нуля, поэтому у меня нет кода вручную.

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