Reputation:
I'm getting an Error when trying to execute the skip method. The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'.
I'm well aware that the orderby must be called prior to calling the skip and I am calling it prior to the skip in another function directly preceding the call.
AddOrderBy(AdvTitleResults, ColumnNumber, OrderByDesc);
var SearchTitles = AdvTitleResults.Skip(PageNum * NumberOfResults)
.Take(NumberOfResults).ToList();
The order by function looks like this the default assures that it is always assigned:
private void AddOrderBy(IQueryable<Title> Results, int ColumnNumber, bool OrderByDesc)
{
switch (ColumnNumber)
{
case 1:
if (OrderByDesc)
Results = Results.OrderByDescending(t => t.FK_ContentType);
else
Results = Results.OrderBy(t => t.FK_ContentType);
break;
case 2:
if (OrderByDesc)
Results = Results.OrderByDescending(t => t.TitleFullName);
else
Results = Results.OrderBy(t => t.TitleFullName);
break;
default:
if (OrderByDesc)
Results = Results.OrderByDescending(t => t.ID);
else
Results = Results.OrderBy(t => t.ID);
break;
}
}
Could anyone explain why this doesn't work?
Upvotes: 1
Views: 1683
Reputation: 101701
Because you are not actually changing the AdvTitleResults
, you are changing the value of your parameter. You need to use ref
keyword to make it work:
AddOrderBy(ref AvTitleResults, ColumnNumber, OrderByDesc);
private void AddOrderBy(ref IQueryable<Title> Results,
int ColumnNumber,
bool OrderByDesc)
Or you can use the LINQ style and make it an extension method, and return the query:
private IOrderedQueryable<Title> AddOrderBy(this IQueryable<Title> Results, int ColumnNumber, bool OrderByDesc)
{
switch (ColumnNumber)
{
case 1:
if (OrderByDesc)
return Results.OrderByDescending(t => t.FK_ContentType);
else
return Results.OrderBy(t => t.FK_ContentType);
break;
case 2:
if (OrderByDesc)
return Results.OrderByDescending(t => t.TitleFullName);
else
return Results.OrderBy(t => t.TitleFullName);
break;
default:
if (OrderByDesc)
return Results.OrderByDescending(t => t.ID);
else
return Results.OrderBy(t => t.ID);
break;
}
}
This way you can call it like any other LINQ method:
var SearchTitles = AdvTitleResults
.AddOrderBy(ColumnNumber, OrderByDesc)
.Skip(PageNum * NumberOfResults)
.Take(NumberOfResults)
.ToList();
Edit:
isn't IQueryable a class shouldn't this be pass by ref by default?
IQueryable<Title>
is not a class but yes it's a reference type. But reference types are not actually passed by reference.When you pass a referece type, the reference value that your variable holds will be copied into a new variable.It's something like this:
string foo = "Foo";
string bar = foo; // copy foo's reference into bar
Now if you assign a new reference to bar
it won't change the foo
:
bar = "bar";
Because they are distinct variables that holds a reference to same address.But when you use ref
keyword the reference value is not copied.Instead you can think like the variable itself is passed.That's the easiest way to understand that. I don't know how to reproduce this behaviour in C# syntax.
Upvotes: 2