2
votes

I need to apply custom server sorting on Kendo grid. He are my entities:

public class User
{
    public virtual ICollection<Region> Regions { get; set; }
    //other properties 
} 

public class Region 
{
    public string Name { get; set; }
}

I want to sort users by first region's Name in the Regions collection. For other sorting, filtering and paging .ToDataSourceResult(request) extension method is used but it seems that my scenario is not supported out of the box. That's why I tried to sort IQuearable manually first, remove SortDescriptor and then call .ToDataSourceResult(request):

    private IQueryable<User> FilterByRegions(IQueryable<User> users, IList<SortDescriptor> sortings)
    {
        var regionsSort = sortings?.FirstOrDefault(x => x.Member == "Regions");
        if (regionsSort == null)
            return users;

        sortings.Remove(regionsSort);

        Expression<Func<User, object>> exp = user => user.Regions.OrderBy(x => x.Name).Select(x => x.Name).FirstOrDefault();

        if (regionsSort.SortDirection == ListSortDirection.Ascending)
            return users.OrderBy(exp);
        else
            return users.OrderByDescending(exp);
    }

Usage:

    public ActionResult Read([DataSourceRequest] DataSourceRequest request)
    {
        IQueryable<User> users = _userApplicationService.GetAll();

        users = FilterByRegions(users, request.Sorts);

        DataSourceResult result = users.ToDataSourceResult(request);
        return Json(result, JsonRequestBehavior.AllowGet);
    }

But it seems that calling .ToDataSourceResult(request) ignore my previous sorting.

How can I achieve desired result? Is it possible to add some custom logic to IQueryable before using .ToDataSourceResult(request)?

I know that it's possible to construct query manually using DataSourceRequest request but it's a bummer because I have a lot of different filters and sortings.

Thank you.

1
It is not ignoring. If you have other sorts you need create different expression. It is how Linq is working. Please note that you can have only one OrderBy.... Any further one will replace previous one. In Linq you need to use ThenBy.... My advice would be create projection when you will explicit send region name, and then modify request sorts to add new projection property. - Marcin
You can always try something similar as here - Petr Ondrusek

1 Answers

0
votes

I had a similar requirement where I had to implement custom server side pagination and sorting with Kendo Grid. According to this post, you should change the request parameter in the ToDataSourceResult extension method to be an empty request instead of passing in the parameter request. So DataSourceResult result = users.ToDataSourceResult(request); should be changed to DataSourceResult result = users.ToDataSourceResult(new DataSourceRequest());. Doing this helped me implement the server side paging and sorting correctly.