【问题标题】:How to load a Model into _Layout.cshtml and share it among various Views?如何将模型加载到 _Layout.cshtml 并在各种视图之间共享?
【发布时间】:2013-09-18 18:28:54
【问题描述】:

我有一个处理“课程”的 MVC4 项目。整个应用程序中的许多页面都需要处理课程列表 - 用户配置文件需要拉出列表,/Courses 的索引视图需要拉出列表等。

由于几乎总是需要这些数据,因此我想将其作为初始请求的一部分加载,因此我只需查询数据库一次。

我想象一个场景,数据被放置在 Layout.cshtml 中,然后其他视图可以根据需要访问模型数据,尽管我没有看到实现这一点的明确方法。我想我可以把问题分成两部分:

  1. 获取加载到 Layout.cshtml 中的数据
  2. 从其他视图访问此数据

我在这两个方面都有点卡住 - 我怎样才能做到这一点?

【问题讨论】:

  • @AlexAr 那不是一回事
  • "所以我只需要查询一次数据库" -- 每个请求完全独立运行,所以无论你做什么,每次都会运行查询。当然,规则的例外是如果您实现某种形式的缓存;不过,关键在于,仅在比单个操作更高的级别运行查询本身并不能使其可用于所有其他操作,而无需再次运行查询。
  • @Chris - 我的意思是有一次参加课程。随后的调用将用于其他数据 - 每个会话只会加载一次课程。这有意义吗?
  • 我就是这么说的。除非您使用 memcache 或其他东西显式缓存查询结果,并从该缓存加载查询的后续请求而不是向数据库发出查询,否则它每次查询,即使它已经完成一直到 global.asax 级别——每个请求都是唯一的,并且不与最后一个共享任何内容。

标签: asp.net-mvc asp.net-mvc-3 asp.net-mvc-4


【解决方案1】:

您应该使用CacheOutputCache,将此列表放入Partial View,然后在您需要的任何地方渲染:

1) 创建一个Action 来填充Partial View。此视图将被缓存最长持续时间,然后任何访问都不会产生任何开销:

[NonAction]
[OutputCache(Duration = int.MaxValue, VaryByParam = "none")]
public ActionResult GetCourses()
{
  List<Course> courses = new List<Course>();

  /*Read DB here and populate the list*/

  return PartialView("_Courses", courses);
}

2) 以同样的方式使用Chache 填充Partial View

[NonAction]
public ActionResult GetCourses()
{
  List<Course> courses = new List<Course>();

  if (this.HttpContext.Cache["courses"] == null)
  {
    /*Read DB here and populate the list*/

    this.HttpContext.Cache["courses"] = courses;
  }
  else
  {
    courses = (List<Course>)this.HttpContext.Cache["courses"];
  }

  return PartialView("_Courses", courses);
}

3) 通过Html.ActionHtml.RenderAction 呈现此视图:

@Html.Action("GetCourses", "ControllerName")

@{ Html.RenderAction("GetCourses", "ControllerName"); }

更多关于缓存的信息:Improving Performance with Output Caching

【讨论】:

  • 感谢 Fals,我会试一试。你介意给我看看 _Courses 部分的样子吗?
  • 好吧,如果您只需要课程列表,请使用 (2),然后根据需要在视图中渲染它!您可以访问 this.HttpContext.Cache["courses"] 或者您可以在 ViewBag 或 ViewData 中引用它,然后在您需要的任何地方迭代生成您需要的任何 HTML!我只是提出了一个缓存这个的想法!
  • 我问的原因是因为我试图从多个视图访问这些数据 - 不一定是部分视图。我应该把这个部分放在 Layout.cshtml 中吗?如果是这样,其他视图如何访问数据?
  • 或者你是说我应该有一个需要数据的不同部分视图,每个视图都从缓存中加载?这对我来说很有意义......再次感谢您的耐心
【解决方案2】:

我有两个答案,因为我不确定我是否理解你的愿望。

1) 创建静态辅助方法:

public static class Helper
{
  public static List<Course> GetCourses()
   {
    return db.Courses.ToList();
    }

}

然后你可以在 View 或 Layout 中到处调用它:

@Helper.GetCourses()

2) 我不希望在ViewsLayout 中呈现业务逻辑。我会创建BaseController。在此控制器中获取 List&lt;Course&gt;。其他控制器应该继承自BaseController。因此,在任何控制器的方法中,您都可能拥有相同的 List&lt;Course&gt; 实例。

【讨论】:

    【解决方案3】:

    将课程存储在 HttpContext.Current.Items 中,这会缓存适合您情况的一个请求的项目。 或者使用一些第三方缓存组件如memcache

    【讨论】:

      猜你喜欢
      • 2018-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多