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>
我不认为这是数据表的问题。在您的代码中,第一行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)的提供程序。
合并你的allProviders
和filteredProviders
变量,并调用ToList()
后,你已经应用了所有可能的过滤器和你的跳取,看看是否提高了你的速度。
在AjaxHandler方法的第一行中,有var allProviders = _db.CareProviders.ToList();
,它将加载表中的所有内容。是那件大的吗?…如果是这样,那是你的问题。
filteredProviders = _db.CareProviders.ToList()
行也将从表中加载所有内容并将其具体化。Where
将在物化数据上执行,并且代码后面的Take
方法将从已经物化的数据中提取一小部分(原因相同)。
从DB中进行选择和物化需要很长时间。