0

想象一下,您在 ASP.Net MVC 中有一个嵌入了多个局部视图,它们独立工作并通过(子操作)View加载自己的模型。Html.Action现在每个单独的部分视图都需要从数据库中加载某些项目。就性能而言,将所有此类数据库调用组合在一起并使用一个查询而不是通过每个单独的子操作逐个预加载相同类型的所有项目会更有效。

例如,假设我们有以下结构:

  • 索引(查看)
    • 主菜单(子操作/部分视图)
      • 这将加载 ID 为 1 和 2 的部分
    • 主要内容(儿童动作/局部视图)
      • 这将加载 ID 为 3、4 和 5 的部分
    • 相关部分(儿童行动/部分视图)
      • 这将加载 ID 为 6 和 7 的部分
    • ...

现在在上述场景中,上面的每个子操作将分别进行各自的数据库调用以加载其自己的模型所需的部分。

为了提高性能,我们需要一种方法,在我们执行每个动作或子动作之前,此类数据库项目请求被“注册”,然后能够一起加载所有项目。然后,当 Action 或 Child Action 需要使用此类数据库项目时,它们将已经完全预加载。

我们正在考虑使用附加到每个动作和子动作的动作过滤器,说明请求了哪些项目,但不幸的是,该OnActionExecuting方法在每个动作被调用之前被单独调用。

我们想要类似于动作过滤器的东西,但不是在每次调用之前执行,而是在调用任何动作/子动作之前在请求的开头执行。通过这种方式,我们可以注册所有此类数据库项目需求并将它们一起加载。

类似于OnInitAsp.Net Web 窗体中的事件,首先调用所有用户控件和控件的 OnInit,然后调用 ASP.Net Web 窗体生命周期中的其他事件。


或者,也许您可​​以提供与我们要求类似的不同解决方案?

4

2 回答 2

3

子操作明确用于不相关的内容:无论如何,您实际上无法合理地组合在单个数据库查询中。如果它都是相关的东西并且您可以一次查询所有内容,那么只需将其全部添加到视图模型中,并使用带有RenderPartial.

于 2013-11-21T15:28:56.520 回答
2

实际上,无法预测视图中将调用哪些子操作。此外,您可能嵌套了对子操作的调用、来自布局的调用等。

在您的情况下,我看到了两种优化性能的方法:1)使用缓存 - 它会提高进一步请求的性能,但不是第一个 2)而不是只有子操作 - 使用部分视图。在这种情况下,您的主要 Index 操作将加载所有必要的项目,构建一个包含属性 MenuItems、Content、RelatedSections 的模型并将它们传递给 Index 视图。然后从索引视图中调用 RenderPartial 并将相应的数据作为模型传递给这个部分。如果您需要 AJAX 功能来检索页面的更新部分 - 那么您需要为每个部分视图创建单独的操作。

简而言之 - 对正常请求使用 RenderPartial,在 AJAX 请求的情况下对每个视图使用 Actions。

如果您不打算使用 AJAX - 那么最好只使用 RenderPartial 方法,因为 Action 更重并且工作速度会慢一点,因为路由、控制器的实例化等涉及为子操作呈现 HTML。

于 2013-11-21T15:27:21.710 回答