jQuery DataTable 和 MVC 服务器端处理
jQuery DataTable and MVC server side processing
所以我在 MVC 中为 jQuery 数据 table 实现了服务器端处理,我正在显示 1 to 10 of 8,037 entries
(带分页)。但是,当我导航到带有 table 的页面时,第一次加载需要很长时间(5 到 10 秒)。在我的控制器中,我将其设置为仅记录 10 条记录 (iDisplayLength)
:
var displayedProviders = filteredProviders
.Skip(param.iDisplayStart)
.Take(param.iDisplayLength);
因此,当我第一次使用 table 导航到页面或使用分页时,它应该一次只能加载 10 条记录。
谁能告诉我为什么第一次加载需要这么长时间?我担心的是它将整个 table 加载到 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 数据表脚本:
<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>
在 AjaxHandler 方法的第一行中,有 var allProviders = _db.CareProviders.ToList();
将从 table 加载所有内容。是大号的吗? ... 如果是,那是你的问题。
另外,行 filteredProviders = _db.CareProviders.ToList()
将从 table 加载 一切 并将其具体化。 Where
将在物化数据上执行,并且代码后面的 Take
方法将从已经物化的数据中取出一小部分(同样的原因)。
是数据库中的选择和实现时间比较长。
我认为这不是数据表问题。在您的代码中,第一行 var allProviders = _db.CareProviders.ToList();
立即访问您的数据库并将所有提供程序加载到内存中。只有在加载到内存中之后,您才会使用 skip 和 take 进行过滤,因此您会遇到初始查询执行开销。更糟糕的是,如果您有过滤条件,您 运行 filteredProviders = _db.CareProviders.ToList()
会访问您的数据库并重新执行整个操作。
记住,当 linq 使用延迟执行时,调用 ToList()
告诉它 "OK, I want this now." 它停止构建表达式树,访问数据库,并将结果转储到列表中,并完成任何进一步的过滤在列表本身上。
你的初始前提是正确的。 运行ning var model = _db.CareProviders
.OrderBy(row => row.ProviderId).Skip((pageNumber - 1) * pageResults)
.Take(pageResults).ToList();
确实只会 return 您想要的行,只要您使用的提供程序能够理解 skip and take(EF 可以)。
合并您的 allProviders
和 filteredProviders
变量,仅在您应用所有可能的过滤器和跳过后才调用 ToList()
,看看这是否会提高您的速度。
所以我在 MVC 中为 jQuery 数据 table 实现了服务器端处理,我正在显示 1 to 10 of 8,037 entries
(带分页)。但是,当我导航到带有 table 的页面时,第一次加载需要很长时间(5 到 10 秒)。在我的控制器中,我将其设置为仅记录 10 条记录 (iDisplayLength)
:
var displayedProviders = filteredProviders
.Skip(param.iDisplayStart)
.Take(param.iDisplayLength);
因此,当我第一次使用 table 导航到页面或使用分页时,它应该一次只能加载 10 条记录。
谁能告诉我为什么第一次加载需要这么长时间?我担心的是它将整个 table 加载到 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 数据表脚本:
<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>
在 AjaxHandler 方法的第一行中,有 var allProviders = _db.CareProviders.ToList();
将从 table 加载所有内容。是大号的吗? ... 如果是,那是你的问题。
另外,行 filteredProviders = _db.CareProviders.ToList()
将从 table 加载 一切 并将其具体化。 Where
将在物化数据上执行,并且代码后面的 Take
方法将从已经物化的数据中取出一小部分(同样的原因)。
是数据库中的选择和实现时间比较长。
我认为这不是数据表问题。在您的代码中,第一行 var allProviders = _db.CareProviders.ToList();
立即访问您的数据库并将所有提供程序加载到内存中。只有在加载到内存中之后,您才会使用 skip 和 take 进行过滤,因此您会遇到初始查询执行开销。更糟糕的是,如果您有过滤条件,您 运行 filteredProviders = _db.CareProviders.ToList()
会访问您的数据库并重新执行整个操作。
记住,当 linq 使用延迟执行时,调用 ToList()
告诉它 "OK, I want this now." 它停止构建表达式树,访问数据库,并将结果转储到列表中,并完成任何进一步的过滤在列表本身上。
你的初始前提是正确的。 运行ning var model = _db.CareProviders
.OrderBy(row => row.ProviderId).Skip((pageNumber - 1) * pageResults)
.Take(pageResults).ToList();
确实只会 return 您想要的行,只要您使用的提供程序能够理解 skip and take(EF 可以)。
合并您的 allProviders
和 filteredProviders
变量,仅在您应用所有可能的过滤器和跳过后才调用 ToList()
,看看这是否会提高您的速度。