Reputation: 82216
Question:
I have a generic list, like this:
System.Collections.Generic.List<Question> myquestions = new System.Collections.Generic.List<Question>();
And I have a paging example, using a LINQ table acquried from database, doing this for paging:
var questions = context.Questions
.OrderBy(sidx + " " + sord)
.Skip(pageIndex * pageSize)
.Take(pageSize);
Right now, for paging my populated from code list, I have:
var questionss = myquestions
.OrderBy(x => x.Id)
.Skip(pageIndex * pageSize)
.Take(pageSize);
And what I want is being able to order "myquestions" by a string as in the above example. Is that possible?
Upvotes: 2
Views: 4008
Reputation: 82216
Bahaha, now I'm gonna cry:
Trying to implement dtb's solution, I saw the problem:
OrderByField<T>(IQueryable<T> q,
Returns IQueryable while inputting IQueryable... lol bs. So, the real question is how to convert List to be iQueryable.
Which, in fact is dead simple:
var list = new List<T>();
var queryable = list.AsQueryable();
then
queryable.OrderBy(sidx + " " + sord);
So the final solution is as trivial as:
myquestions.AsQueryable().OrderBy(sidx + " " + sord).Skip(pageIndex * pageSize).Take(pageSize);
Which also means Linq.Table implements IQueryable, which makes sense IMHO.
Edit:
Note: This requires reference to: Dynamic.dll (not System.Dynamic.dll)
as well as
using System.Linq.Dynamic;
If you don't reference Dynamic.dll, or don't declare the using directive, you'll get an error on AsQueryable().
Upvotes: 3
Reputation: 700442
You can chain the extension methods in separate statements thanks to the lazy execution, which means that you can add different sorting depending on a condition:
IOrderedQueryable<Question> sorted;
switch (sort) {
case "Id": sorted = myquestions.OrderBy(x => x.Id);
case "Name": sorted = myquestions.OrderBy(x => x.Name);
case "Size": sorted = myquestions.OrderBy(x => x.Size);
case "Id Desc": sorted = myquestions.OrderByDescending(x => x.Id);
case "Name Desc": sorted = myquestions.OrderByDescending(x => x.Name);
case "Size Desc": sorted = myquestions.OrderByDescending(x => x.Size);
default: throw new NotImplementedException();
}
var questions = sorted.Skip(pageIndex * pageSize).Take(pageSize);
You can even add a secondary sorting (or as many as you like, after the first they are all the same):
IOrderedQueryable<Question> sorted;
switch (sort) {
case "Id": sorted = myquestions.OrderBy(x => x.Id);
case "Name": sorted = myquestions.OrderBy(x => x.Name);
case "Size": sorted = myquestions.OrderBy(x => x.Size);
case "Id Desc": sorted = myquestions.OrderByDescending(x => x.Id);
case "Name Desc": sorted = myquestions.OrderByDescending(x => x.Name);
case "Size Desc": sorted = myquestions.OrderByDescending(x => x.Size);
default: throw new NotImplementedException();
}
switch (sort2) {
case "Id": sorted = sorted.ThenBy(x => x.Id);
case "Name": sorted = sorted.ThenBy(x => x.Name);
case "Size": sorted = sorted.ThenBy(x => x.Size);
case "Id Desc": sorted = sorted.ThenByDescending(x => x.Id);
case "Name Desc": sorted = sorted.ThenByDescending(x => x.Name);
case "Size Desc": sorted = sorted.ThenByDescending(x => x.Size);
}
var questions = sorted.Skip(pageIndex * pageSize).Take(pageSize);
Upvotes: 3
Reputation: 15867
You could look at Dynamic Linq. IIRC it was a sample that shipped with VS2008, I'm not 100% sure if it's still included in VS2010.
Upvotes: 1
Reputation: 1501163
One option is to create a dictionary from each possible ordering string to an appropriate delegate. For example:
Dictionary<string, Func<IEnumerable<Question>, IEnumerable<Question>> orderings =
new Dictionary<string, Func<IEnumerable<Question>, IEnumerable<Question>>()
{
{ "Id", questions => questions.OrderBy(x => x.Id) },
{ "Title", questions => questions.OrderBy(x => x.Title) },
{ "Answer", questions => questions.OrderBy(x => x.Answer) },
{ "Id Desc", questions => questions.OrderByDescending(x => x.Id) },
{ "Title Desc", questions => questions.OrderByDescending(x => x.Title) },
{ "Answer Desc", questions => questions.OrderByDescending(x => x.Answer) },
};
Then you can find that mapping at execution time, and apply the function.
Upvotes: 1
Reputation: 43523
Please check my answer to another question on how to build a custom OrderBy
predicate using Expression
from a given String
.
Upvotes: 2