jQuery数据表和MVC服务器端处理

本文关键字:服务器端 处理 MVC 数据表 jQuery | 更新日期: 2023-09-27 18:12:24

所以我在MVC中实现了服务器端处理jQuery数据表,我显示1 to 10 of 8,037 entries(带分页)。然而,当我导航到带有表格的页面时,第一次加载需要很长时间(5到10秒)。在我的控制器中,我将其设置为仅取10条记录(iDisplayLength):

        var displayedProviders = filteredProviders
            .Skip(param.iDisplayStart)
            .Take(param.iDisplayLength);

因此,当我第一次导航到带有表的页面或我使用分页时,它应该一次只加载10条记录。

谁能告诉我为什么第一次加载花了这么长时间?我担心的是,它将整个表加载到Json请求中,这一开始会减慢速度。这不是我在实现服务器端处理时所想到的。有办法解决这个问题吗?如果我实现:

    var model = _db.CareProviders
.OrderBy(row => row.ProviderId).Skip((pageNumber - 1) * pageResults)
    .Take(pageResults).ToList();

这将只显示10个结果,没有更多?

模型:

    public class jQueryDataTableParamModel
    {
        /// <summary>
        /// Request sequence number sent by DataTable,
        /// same value must be returned in response
        /// </summary>       
        public string sEcho { get; set; }
        /// <summary>
        /// Text used for filtering
        /// </summary>
        public string sSearch { get; set; }
        /// <summary>
        /// Number of records that should be shown in table
        /// </summary>
        public int iDisplayLength { get; set; }
        /// <summary>
        /// First record that should be shown(used for paging)
        /// </summary>
        public int iDisplayStart { get; set; }
        /// <summary>
        /// Number of columns in table
        /// </summary>
        public int iColumns { get; set; }
        /// <summary>
        /// Number of columns that are used in sorting
        /// </summary>
        public int iSortingCols { get; set; }
        /// <summary>
        /// Comma separated list of column names
        /// </summary>
        public string sColumns { get; set; }
    }
}

控制器:

    public ActionResult AjaxHandler(jQueryDataTableParamModel param)
    {
        var allProviders = _db.CareProviders.ToList();
        IEnumerable<CareProvider> filteredProviders;
        if (!string.IsNullOrEmpty(param.sSearch))
        {
            filteredProviders = _db.CareProviders.ToList()
                     .Where(c => c.ProviderId.Contains(param.sSearch)
                                 ||
                      c.CareServiceType.Contains(param.sSearch)
                                 ||
                                 c.CareServiceName.Contains(param.sSearch));
        }
        else
        {
            filteredProviders = allProviders;
        }
        var displayedProviders = filteredProviders
            .Skip(param.iDisplayStart)
            .Take(param.iDisplayLength);
        var result = from c in displayedProviders
                     select new[] { Convert.ToString(c.ProviderId), c.CareServiceType, c.CareServiceName, c.Email };
        return Json(new
        {
            sEcho = param.sEcho,
            iTotalRecords = allProviders.Count(),
            iTotalDisplayRecords = filteredProviders.Count(),
            aaData = result
        },
                         JsonRequestBehavior.AllowGet);
    }

Jquery DataTable Script:

<script type="text/javascript">
    $(function () {
        // Initialize Example 2
        // $('#example2').dataTable();
        $('#example2').dataTable({
            "bServerSide": true,
            "sAjaxSource": "AdminPanel/AjaxHandler",
            "bProcessing": true,
            "aoColumns": [
                            { "sName": "ProviderId" },
                            { "sName": "CareServiceType" },
                            { "sName": "CareServiceName" },
                            { "sName": "Email" }
            ]
        });
    });
</script>

jQuery数据表和MVC服务器端处理

我不认为这是数据表的问题。在您的代码中,第一行var allProviders = _db.CareProviders.ToList();立即击中数据库并将所有提供程序加载到内存中。只有在加载到内存之后,才会使用skip和take进行过滤,这样就达到了初始查询执行开销。更糟糕的是,如果您有一个过滤条件,您可以运行filteredProviders = _db.CareProviders.ToList(),它会访问数据库并重新执行整个操作。

记住,当linq使用延迟执行时,调用ToList()告诉它"好,我现在想要这个"。它停止构建表达式树,访问数据库,并将结果转储到列表中,任何进一步的过滤都在列表本身上完成。

你最初的前提是正确的。运行var model = _db.CareProviders .OrderBy(row => row.ProviderId).Skip((pageNumber - 1) * pageResults) .Take(pageResults).ToList();确实只会返回您想要的行,只要您使用的是理解跳过和取(EF)的提供程序。

合并你的allProvidersfilteredProviders变量,并调用ToList()后,你已经应用了所有可能的过滤器和你的跳取,看看是否提高了你的速度。

在AjaxHandler方法的第一行中,有var allProviders = _db.CareProviders.ToList();,它将加载表中的所有内容。是那件大的吗?…如果是这样,那是你的问题。

filteredProviders = _db.CareProviders.ToList()行也将从表中加载所有内容并将其具体化。Where将在物化数据上执行,并且代码后面的Take方法将从已经物化的数据中提取一小部分(原因相同)。

从DB中进行选择和物化需要很长时间。