I have list of data and user defined sort list and I need to sort my source list based on total numbers defined in the sort list object. It should be dynamic so that the user can freely create his own sort list preference. In my sample code I used Person class. The class may have more properties in the future that's why I want that my sort expression is dynamic too. I used PropertyName to convey a lookup for property. In my example below I have list of person and I have list of sort preference. In my first example I want to sort the person list by Name ascending, then by Age descending. Can someone help me have a LINQ extension? I saw an example in this post Dynamic Linq Order By Variable
The scenario in that post is quite similar to mine except this one is using fixed properties. What I want to achieve is dynamic like the following.
- Sort expression is dynamic that is I need to look up for property name that has matching in my sort expression. If any found sort based on sort direction.
- Sort execution should be based on how many sort items are defined in the sort list. For example loop through the sort list and do OrderBy (if ascending), OrderByDescending (if descending), ThenBy, ThenBy so on and so fort. For example I have 2 sort order then the source list should be ordered by then by. If I have 5 then the list should sorted in 1 "OrderBy (desc or asc)" and 4 "ThenBy (desc or asc)". The chain should not be broken that for example given 4 sort order and all are ascending it will become persons.OrderBy(prop1).ThenBy(prop2).ThenBy(prop3).ThenBy(prop4).
C# Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SortDemo
{
class Program
{
static void Main(string[] args)
{
var persons = new List<Person>();
persons.Add(new Person { Name="George", Age=25, Group="A", State="LA"});
persons.Add(new Person { Name = "Anna", Age = 20, Group = "B", State = "CA" });
persons.Add(new Person { Name = "Xenna", Age = 30, Group = "A", State = "DC" });
persons.Add(new Person { Name = "Sam", Age = 40, Group = "C", State = "IL" });
persons.Add(new Person { Name = "Elise", Age = 21, Group = "B", State = "LA" });
persons.Add(new Person { Name = "Josh", Age = 29, Group = "C", State = "MI" });
persons.Add(new Person { Name = "Mike", Age = 34, Group = "A", State = "NY" });
persons.Add(new Person { Name = "Bernard", Age = 27, Group = "C", State = "WY" });
var sorts = new List<Sort>();
sorts.Add(new Sort { PropertyName = "Age", SortOrder = 2, Direction = "Descending" });
sorts.Add(new Sort { PropertyName="Name", SortOrder=1, Direction="Ascending"});
//sort by two properties
foreach(var sort in sorts.OrderBy(x=>x.SortOrder))
{
//OrderBy if sort direction is Ascending
//OrderByDescending if sort direction is Descending
var sortedPersons = persons.OrderBy(x=>PropertyName==sort.PropertyName);
//expected results
//order persons by Name ascending
//then by Age Descending
}
//another example
var sorts1 = new List<Sort>();
sorts1.Add(new Sort { PropertyName = "Name", SortOrder = 4, Direction = "Descending" });
sorts1.Add(new Sort { PropertyName = "Age", SortOrder = 1, Direction = "Ascending" });
sorts1.Add(new Sort { PropertyName = "State", SortOrder = 3, Direction = "Ascending" });
sorts1.Add(new Sort { PropertyName = "Group", SortOrder = 2, Direction = "Ascending" });
//sort by four properties
foreach (var sort in sorts1.OrderBy(x => x.SortOrder))
{
//OrderBy if sort direction is Ascending
//OrderByDescending if sort direction is Descending
var sortedPersons1 = persons.OrderBy(x => PropertyName == sort.PropertyName);
//expected results
//order persons by Age Ascending
//then by Group Ascending
//then by State Ascending
//then by Name Descending
}
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public string Group { get; set; }
public string State { get; set; }
}
public class Sort
{
public string PropertyName { get; set; }
public int SortOrder { get; set; }
public string Direction { get; set; }
}
}