Entity Framework: combining paging with Dynamic LINQ OrderBy

c# dynamic-linq entity-framework linq

Question

I am retriveing some data using Entity Framework like so:

var items = GetItems(storeNumber);

Sort(items);

Page(items);

return await items.ToListAsync();

I have these private helper methods:

private IQueryable<Item> GetItems(string storeNumber)
{
    return _dbContext.Items.Where(x => x.StoreNumber == storeNumber);
}

I sort the results using Dynamic LINQ.

private void Sort(IQueryable<Item> items, string fieldToSort, string sortDirection)
{
    items = items.OrderBy($"{fieldToSort} {sortDirection}");
}

In my Page method I get the exception

The method 'OrderBy' must be called before the method 'Skip'

private void Page(IQueryable<Item> items, int skip, int take)
{
    items = items.Skip(skip).Take(take);
}

I had suspected that the reason for the error was because items needs to be IOrderedQueryable<Item> but there is no overload for the Dynamic LINQ OrderBy which returns IOrderedQueryable<T>. If I extract the Sort and Page code into the same method, using var it's no longer an issue, it infers the type. The problem seems to be using the IQueryable interface when sorting and paging. Is there a way I can break up this logic into separate methods but still use Dynamic LINQ for sorting?

Any help is much appreciated.

1
1
9/11/2017 10:59:56 AM

Accepted Answer

You should return the newly constructed IQueryable from the Sort() and the Page() methods, just as you do for GetItems(). If you "rewrite" a parameter value inside a method like this, it has no effect on the value originally passed in to the parameter, because C# uses by-value parameter passing semantics

See this for more reference: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/passing-parameters

2
9/11/2017 11:28:57 AM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow