5

我正在尝试为我的网站创建一个菜单。它需要满足以下要求

  • 它必须是数据库驱动的,从数据库中提取数据以建立菜单结构
  • 从数据库中提取的数据需要缓存 - 我不想为每个页面请求访问数据库

目前,我有一个简单的示例正在运行,但我不知道如何集成缓存。我想我可能不得不重新设计我这样做的整个方式。这里是:

我有一个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();
    }
}

现在,每当我的控制器上的任何操作被命中时,都会调用ProductMenuAttribute类中的OnActionExecuted方法,这将设置 ViewData,最终将在我的Site.Master上使用它来从数据库构建我的菜单,这时候我调用任何动作。

现在的问题是 - 我如何在这个场景中添加缓存?我不知道从哪里开始,并且感觉我的解决方案不可缓存。

4

3 回答 3

6

我认为我真正想要的是使用 MVC Futures 项目中的Html.RenderAction()辅助扩展。

这个想法是使用上面的方法来调用控制器上的一个动作,这将通过从数据库中提取数据来生成 HTML 菜单结构。然后我还使用简单的输出缓存来缓存数据几分钟..

这是迄今为止我发现的最简单的方法来实现我想要的。

编辑: Phil Haack 最近写了一篇关于这个的博客 - Html.RenderAction 和 Html.Action。一篇很棒的博客文章,涵盖了我所有的确切需求,并解释了所有问题。

为了让缓存正常工作,我需要将我的Html.RenderAction()调用放在ViewUserControl中,并设置如下 OutputCaching 指令:

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

然后我用 调用上述Html.RenderPartial()内容,瞧,一切正常!

于 2010-02-09T13:21:17.487 回答
1

您可以将存储库修改为可感知缓存:请参阅这两个问题: 缓存存储库http 缓存

于 2009-12-28T11:30:07.573 回答
0

我已经通过使用 Enterprise Library Caching 块来做到这一点。您检查缓存数据,如果没有缓存数据,则从数据库中的数据创建 html 字符串并将其放入缓存中,以便稍后在搜索缓存数据时,您可以输出纯字符串:D

只是提到这样做的代码是在静态类中。生病发布示例,但我正在从头开始在 MVC2 中重写该应用程序,所以我没有手动代码。

于 2010-10-31T15:24:15.523 回答