I'm trying to build some code for dynamically sorting a Linq IQueryable<>.
The obvious way is here, which sorts a list using a string for the field name
http://dvanderboom.wordpress.com/2008/12/19/dynamically-composing-linq-orderby-clauses/
However I want one change - compile time checking of field names, and the ability to use refactoring/Find All References to support later maintenance. That means I want to define the fields as f=>f.Name, instead of as strings.
For my specific use I want to encapsulate some code that would decide which of a list of named "OrderBy" expressions should be used based on user input, without writing different code every time.
Here is the gist of what I've written:
var list = from m Movies select m; // Get our list
var sorter = list.GetSorter(...); // Pass in some global user settings object
sorter.AddSort("NAME", m=>m.Name);
sorter.AddSort("YEAR", m=>m.Year).ThenBy(m=>m.Year);
list = sorter.GetSortedList();
...
public class Sorter<TSource>
...
public static Sorter<TSource> GetSorter(this IQueryable<TSource> source, ...)
The GetSortedList function determines which of the named sorts to use, which results in a List object, where each FieldData contains the MethodInfo and Type values of the fields passed in AddSort:
public SorterItem<TSource> AddSort(Func<T, TKey> field)
{
MethodInfo ... = field.Method;
Type ... = TypeOf(TKey);
// Create item, add item to diction, add fields to item's List<>
// The item has the ThenBy method, which just adds another field to the List<>
}
I'm not sure if there is a way to store the entire field object in a way that would allow it be returned later (it would be impossible to cast, since it is a generic type)
Is there a way I could adapt the sample code, or come up with entirely new code, in order to sort using strongly typed field names after they have been stored in some container and retrieved (losing any generic type casting)
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…