MVC应用程序中的表连接速度非常慢

Chr*_*ris 1 c# sql asp.net-mvc linq-to-sql database-performance

我有点不知道为什么我的MVC应用程序中的一个ASP视图运行得如此之慢.

我在控制器中使用linq选择一些数据.这很快就会运行:

public ActionResult Progress(int ID)
        {


            var reviewitems = from ri in db.ReviewItems
                         where ri.Enrolment.Course.LearningArea.LearningAreaID == ID && ri.Review.ReviewSeries.StartDate < DateTime.Now && ri.Review.ReviewSeries.EndDate > DateTime.Now && ri.Progress < 2
                         select ri;


            return View("Progress", reviewitems);


        }
Run Code Online (Sandbox Code Playgroud)

然后我在ASP视图中执行foreach循环,遍历已经传递给视图的'reviewitem'类型的数据的每一行.这很快:

<%foreach (var ri in Model)
  {  %>
<tr>
<td><%= ri.Progress %></td>
</tr>
<%} %>   
Run Code Online (Sandbox Code Playgroud)

我需要显示更多信息,因此我需要加入"评论"表(再次提供快速结果),然后加入"学生"表.这就是问题所在,开始耗时超过30秒:

 <%foreach (var ri in Model)
  {  %>
<tr>
<td><%= ri.Review.Student.Surname %></td>
</tr>
<%} %>   
Run Code Online (Sandbox Code Playgroud)

每个评论项目链接到一个独特的学生,所以我不明白为什么这么长时间.有没有人有任何想法,我应该开始寻找为什么它这么慢?据推测它与'Student'表(实际上是一个SQL Server视图)有关,但我可以使用SQL在一秒钟内从中选择所有行?

Dan*_*Dan 6

当您编写LINQ查询时,在您需要数据之前,查询实际上并未执行(请参阅延迟执行).直到您通过ri.Progress进行第一次数据库调用,这是一次调用.

当你要求ri.Review.Student时,你要求提供更多数据.所以你打电话给数据库.因为您处于foreach循环中,所以您只需对该循环中的每个项目调用数据库.

这是一个"Linq n + 1"问题.要解决它,您应该在一个查询中获取所有数据.您可以填充模型类并强烈键入视图,或者我认为您可以使用Linq .Include方法将Student数据包含在选择中

您可以通过启动SQL Server Profiler并执行跟踪来查看正在进行的调用