在ASP.Net MVC中分组预加载数据库项

时间:2013-11-21 14:59:58

标签: asp.net asp.net-mvc asp.net-mvc-4 actionfilterattribute custom-action-filter

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

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

  • 索引(查看)
    • 主菜单(儿童操作/部分视图)
      • 这将加载ID为1&的段。 2
    • 主要内容(儿童行动/部分观点)
      • 这将加载ID为3,4,&的段。 5
    • 相关章节(儿童行动/部分视图)
      • 这将加载ID为6&的段。 7
    • ...

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

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

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

我们希望类似于Action Filters,但不是在每次调用之前执行,而是在调用任何Action / Child Action之前在请求的开头执行它们。这样我们就可以注册所有这些数据库项目要求并将它们加载到一起。

与Asp.Net Web窗体中的OnInit事件类似的东西,首先是所有用户控件的OnInit&调用控件,然后调用ASP.Net Web窗体生命周期中的其他事件。


或许您可以提供与我们要求相似的不同解决方案?

2 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

实际上,无法预测视图中将调用哪些子操作。您也可以嵌套调用子操作,从布局调用等等。

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

在短期内使用RenderPartial进行正常请求,并在AJAX请求的情况下为每个视图执行操作。

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