So, I had the Grid working with Ajax, and that was really awesome as the paging and sorting was very quick. However, we had a problem that larger data sets (30k and more) would have the Grid time out. I believe switching over to a server side binding and grabbing 20 at a time would allow users to get the data. (Please correct me if I'm wrong).
Here's what I had before:
@(Html.Kendo().Grid<
vNPISearch
>()
.Name("npi-grid")
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("NPI_Read", "Pecos"))
.ServerOperation(false)
.PageSize(20))
.Columns(columns =>
{
columns.Template(x => { }).ClientTemplate("#=GetPecosStatus(PecosNPI) #").Width(50);
columns.Bound(x => x.ProviderFirstName).Title("First Name");
columns.Bound(x => x.ProviderLastName).Title("Last Name");
columns.Bound(x => x.ProviderBusinessLocationAddressCity).Title("City");
columns.Bound(x => x.ProviderBusinessLocationAddressState).Title("State");
columns.Bound(x => x.NPI).Title("NPI");
})
.Scrollable()
.Sortable()
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
)
And the NPI_Read looked like:
public
ActionResult NPI_Read([DataSourceRequest] DataSourceRequest request)
{
if
(!String.IsNullOrEmpty(SearchTerm))
{
return
Json(oandpService.GetPecosSearchResults(SearchTerm).ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
}
else
{
return
null
;
}
}
However, the performance was ABSOLUTELY TERRIBLE! For it to grab 55 records it took almost 10 seconds, whereas if I just populated a simple table it would be almost instantly.
So, I wanted to try server side binding.
The view now looks like:
@(Html.Kendo().Grid<
vNPISearch
>()
.Name("npi-grid")
.Columns(columns =>
{
columns.Template(x => { }).ClientTemplate("#=GetPecosStatus(PecosNPI) #").Width(50);
columns.Bound(x => x.ProviderFirstName).Title("First Name");
columns.Bound(x => x.ProviderLastName).Title("Last Name");
columns.Bound(x => x.ProviderBusinessLocationAddressCity).Title("City");
columns.Bound(x => x.ProviderBusinessLocationAddressState).Title("State");
columns.Bound(x => x.NPI).Title("NPI");
})
.Scrollable(src => src.Height("auto"))
.Sortable()
.Pageable()
.DataSource(dataSource => dataSource
.Server()
.PageSize(20)
.Total((int)ViewData["total"])
.Read(read => read.Action("NPI_Read", "Pecos")))
)
And the NPI_Read looks like:
public
ActionResult NPI_Read([DataSourceRequest] DataSourceRequest request)
{
if
(!String.IsNullOrEmpty(SearchTerm))
{
if
(request.PageSize == 0)
{
request.PageSize = 20;
}
IQueryable<vNPISearch> searchResults = oandpService.GetPecosSearchResults(SearchTerm);
if
(request.Sorts.Any())
{
foreach
(SortDescriptor sortDescriptor
in
request.Sorts)
{
if
(sortDescriptor.SortDirection == ListSortDirection.Ascending)
{
switch
(sortDescriptor.Member)
{
case
"ProviderFirstName"
:
searchResults = searchResults.OrderBy(x => x.ProviderFirstName);
break
;
case
"ProviderLastName"
:
searchResults = searchResults.OrderBy(x => x.ProviderLastName);
break
;
case
"ProviderBusinessLocationAddressCity"
:
searchResults = searchResults.OrderBy(x => x.ProviderBusinessLocationAddressCity);
break
;
case
"ProviderBusinessLocationAddressState"
:
searchResults = searchResults.OrderBy(x => x.ProviderBusinessLocationAddressState);
break
;
case
"NPI"
:
searchResults = searchResults.OrderBy(x => x.NPI);
break
;
}
}
else
{
switch
(sortDescriptor.Member)
{
case
"ProviderFirstName"
:
searchResults = searchResults.OrderByDescending(x => x.ProviderFirstName);
break
;
case
"ProviderLastName"
:
searchResults = searchResults.OrderByDescending(x => x.ProviderLastName);
break
;
case
"ProviderBusinessLocationAddressCity"
:
searchResults = searchResults.OrderByDescending(x => x.ProviderBusinessLocationAddressCity);
break
;
case
"ProviderBusinessLocationAddressState"
:
searchResults = searchResults.OrderByDescending(x => x.ProviderBusinessLocationAddressState);
break
;
case
"NPI"
:
searchResults = searchResults.OrderByDescending(x => x.NPI);
break
;
}
}
}
}
else
{
//EF cannot page unsorted data.
searchResults = searchResults.OrderBy(x => x.ProviderLastName);
}
//Apply paging.
if
(request.Page > 0)
{
searchResults = searchResults.Skip((request.Page - 1) * request.PageSize);
}
searchResults = searchResults.Take(request.PageSize);
ViewData[
"total"
] = searchResults.Count();
var result =
new
DataSourceResult()
{
Data = searchResults,
Total = Convert.ToInt32(ViewData[
"total"
])
};
return
Json(result, JsonRequestBehavior.AllowGet);
}
else
{
return
Json(Enumerable.Empty<vNPISearch>().AsQueryable());
}
}
However, when I run the page it immediately returns: Object reference not set to an instance of an object. With Line 21 being highlighted. That line is .DataSource(dataSource => dataSource
So, two questions:
- Is there a way to improve performance with AJAX and large datasets?
- If not, what am I not doing to get server side binding not working?