c# - 使用 EF6+MVC5 渲染网页时性能不佳。为什么?

标签 c# asp.net-mvc entity-framework

我使用 .NET Framework 4.5.1、MVC 5 和 EF 6 开发了一个 Web 应用程序。数据存储在 MySQL 数据库中。 问题是表演真的很糟糕,我找不到原因。有些页面需要几秒钟(最多 10 秒)才能完全加载!

我已经尝试实现在 Web 上找到的一些建议,但它们几乎没有改善。

例如,以下 Controller 从数据库中获取用户列表并将其传递给 View 。

public class UserController : Controller
{
    // GET: /User/
    public async Task<ActionResult> Index()
    {
        using (AuthorDbContext db = new AuthorDbContext())
        {
            return View(await db.Users.OrderBy(u => u.Surname)
                                        .ThenBy(u => u.Name)
                                        .Include(u => u.Company)
                                        .Include(u => u.Department)
                                    .ToListAsync());
        }
    }

    // [...]
}

View 将用户的详细信息打印到 HTML 表中(使用 jQuery 的 DataTable plugin)。

@model IEnumerable<Author.Models.User>
@using Author.Helpers

<div class="geco-button-container">
    @ButtonHelper.CreateButton(Url.RouteUrl("New User"), "Add a new user")
</div>

<table id="longTable" class="longTable">
    <thead>
        <tr>
            <th></th>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Surname)
            </th>
[...]
        </tr>
    </thead>
    <tbody>
    @foreach (var item in Model) {
        <tr@(item.QuittedOn != null && item.QuittedOn.Value < DateTime.Now ? " class=user_dismissed" : "")>
            <td class="tableButton">
                @ButtonHelper.ViewButton(Url.RouteUrl("View User", new RouteValueDictionary {{ "id", item.id }}), "", "Details")
                @if (item.canBeEdited)
                {
                    @ButtonHelper.EditButton(Url.RouteUrl("Edit User", new RouteValueDictionary {{ "id", item.id }}), "", "Edit")
                    @ButtonHelper.DeleteButton(Url.RouteUrl("Delete User", new RouteValueDictionary {{ "id", item.id }}), "", "Delete")
                }
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Surname)
            </td>
[...]
            <td>
                @if (item.Department != null)
                {
                    @Html.RouteLink(item.Department.Code.ToString(), "View Department", new RouteValueDictionary { { "id", item.DepartmentId } }, new Dictionary<string,object> { { "title", item.Department.Description.ToString() } })
                }
            </td>
        </tr>
    }
    </tbody>
</table>
@section Scripts {
    @Scripts.Render("~/Scripts/DataTables-1.9.4/media/js/jquery.dataTables.min.js")
    @Scripts.Render("~/Scripts/longTable.js")
}

当我访问此页面时,需要 5 到 10 秒才能完成加载 698 位用户的列表。

我已经安装了 Glimpse ,它表示问题似乎出在结果页面的呈现上。

Glimpse - HTTP tab

Glimpse - Execution tab

Glimpse - Timeline

如您所见,我实现了一些可以提高性能的技巧,例如:

  • 使用 RouteLinkRouteUrl 代替 ActionLinkActionUrl
  • 使用异步调用
  • 禁用除 RazorViewEngine 之外的所有 View 引擎(在 Global.asax 中)

我在本地机器上以 Debug模式运行应用程序。有人建议将选项 debug="false" 设置到 web.config 中,但我还在 Web 服务器上发布了它,在该服务器上运行该选项,但问题仍然存在。

许多人提示 Entity Framework 的速度慢,但他们通常谈论数百毫秒,而在我的情况下需要几秒钟——这在 Web 场景中确实是不能接受的!

问题是什么?我做错了什么?


更新

我已经安装了 dotTRACE,这是显示用户列表的页面上的结果。

dotTRACE on a page

如您所见,瓶颈在于 Microsoft 框架。

什么是 MappingDataUtilities 类?它的目标是什么?它的函数指的是 Json、Css、TagName、Selectors 等东西呢?

我的代码从不显式调用这些东西。我怎样才能改善他们糟糕的表现?

最佳答案

我强烈建议将 ViewModel 与 DataModel 分离。当这两者是同一件事时,这意味着将所有内容都暴露给您的 ViewModel,即使您只需要少数几个字段。我建议创建一个仅包含您感兴趣的字段的新 ViewModel,然后更新您的 EF 查询以仅选择您需要的字段,而不是在许多表上执行 SELECT *。我相信这会对性能有很大帮助。

关于c# - 使用 EF6+MVC5 渲染网页时性能不佳。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23911706/

相关文章:

asp.net-mvc - ViewBag 访问性能

entity-framework - EF5 Code First 迁移中的程序化数据转换

c# - 为 IQueryable<T> 生成表达式

c# - xamarin.forms 从 xaml 绑定(bind)到属性

c# - 输出行号

c# - 数据 GridView Winforms : FullRowSelect current cell still visible

c# - 1对1关系EF两个外键报错

c# - 将 C# 委托(delegate)与具有可选参数的方法一起使用

asp.net-mvc - TDD - 在 ASP.NET MVC 中测试业务规则/验证

jquery - 如何记住 Kendo Grid 中第二次请求的过滤器值?