Sort list <T> using non-Linq string
Is there a way to sort the List<T> using a string like "Name desc" (same as DataTable.DefaultView.Sort ) and then Linq?
I am trying to replace DataTables with Lists , and I need this to be compatible with the old code.
Decision
using V4Vendetta code I was able to create this extension method, tests show that it works.
public static void SortByString<T>(this List<T> list, string sortString) { if (sortString == null) return; List<string> SortGroups = sortString.Split(',').ToList(); for (int i = SortGroups.Count - 1; i >= 0; i--)// sort from the last group first { string tempColumn = SortGroups[i].Trim().Split(' ')[0]; bool isAsc = SortGroups[i].Trim().Split(' ').Length > 1 ? SortGroups[i].Trim().Split(' ')[1].ToLower() == "asc" ? true : false : true; PropertyInfo propInfo = typeof(T).GetProperty(tempColumn); if (propInfo == null) // if null check to make sure its not just a casing issue. { foreach (PropertyInfo pi in typeof(T).GetProperties()) { if(pi.Name.ToLower() == tempColumn.ToLower()) { tempColumn = pi.Name; propInfo = typeof(T).GetProperty(tempColumn); break; } } } if (propInfo != null) { Comparison<T> compare = delegate(T a, T b) { object valueA = isAsc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null); object valueB = isAsc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null); return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0; }; list.Sort(compare); }else{ throw new IndexOutOfRangeException("Property: '" + tempColumn + "', does not exist in '" + typeof(T).ToString() + "'"); } } } I tried something on these lines, maybe you need to improvise his quote for your needs
private List<Employee> CreateSortList<T>( IEnumerable<Employee> dataSource, string fieldName, SortDirection sortDirection) { List<Employee> returnList = new List<Employee>(); returnList.AddRange(dataSource); // get property from field name passed System.Reflection.PropertyInfo propInfo = typeof(T).GetProperty(fieldName); Comparison<Employee> compare = delegate(Employee a, Employee b) { bool asc = sortDirection == SortDirection.Ascending; object valueA = asc ? propInfo.GetValue(a, null) : propInfo.GetValue(b, null); object valueB = asc ? propInfo.GetValue(b, null) : propInfo.GetValue(a, null); //comparing the items return valueA is IComparable ? ((IComparable)valueA).CompareTo(valueB) : 0; }; returnList.Sort(compare); return returnList; } You need to pass in the appropriate direction of sorting and the name of the field, which will be a property of the class (in my case Employee)
Hope this helps
There is no native support for this type of search, as far as I know. So you have to write your own.
Do not break the string too much. Separate it with commas (,) if you have a sort string like "name asc, age desc" and treat each as a name and direction. Then you can use a reflection of type T to find the property to sort and build a method that performs the necessary comparison.
See this article on codeplex for an example: http://www.codeproject.com/KB/linq/dynamite_dynamic_sorting.aspx
I have had success in the linq dynamic query library in the past: http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query- library.aspx