I found an example in the VS2008 Examples for Dynamic LINQ that allows you to use a SQL-like string (e.g. OrderBy("Name, Age DESC"))
for ordering. Unfortunately, the method included only works on IQueryable<T>
. Is there any way to get this functionality on IEnumerable<T>
?

- 1,062
- 1
- 10
- 21

- 77,456
- 30
- 160
- 194
24 Answers
Just stumbled into this oldie...
To do this without the dynamic LINQ library, you just need the code as below. This covers most common scenarios including nested properties.
To get it working with IEnumerable<T>
you could add some wrapper methods that go via AsQueryable
- but the code below is the core Expression
logic needed.
public static IOrderedQueryable<T> OrderBy<T>(
this IQueryable<T> source,
string property)
{
return ApplyOrder<T>(source, property, "OrderBy");
}
public static IOrderedQueryable<T> OrderByDescending<T>(
this IQueryable<T> source,
string property)
{
return ApplyOrder<T>(source, property, "OrderByDescending");
}
public static IOrderedQueryable<T> ThenBy<T>(
this IOrderedQueryable<T> source,
string property)
{
return ApplyOrder<T>(source, property, "ThenBy");
}
public static IOrderedQueryable<T> ThenByDescending<T>(
this IOrderedQueryable<T> source,
string property)
{
return ApplyOrder<T>(source, property, "ThenByDescending");
}
static IOrderedQueryable<T> ApplyOrder<T>(
IQueryable<T> source,
string property,
string methodName)
{
string[] props = property.Split('.');
Type type = typeof(T);
ParameterExpression arg = Expression.Parameter(type, "x");
Expression expr = arg;
foreach(string prop in props) {
// use reflection (not ComponentModel) to mirror LINQ
PropertyInfo pi = type.GetProperty(prop);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}
Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), type);
LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);
object result = typeof(Queryable).GetMethods().Single(
method => method.Name == methodName
&& method.IsGenericMethodDefinition
&& method.GetGenericArguments().Length == 2
&& method.GetParameters().Length == 2)
.MakeGenericMethod(typeof(T), type)
.Invoke(null, new object[] {source, lambda});
return (IOrderedQueryable<T>)result;
}
Edit: it gets more fun if you want to mix that with dynamic
- although note that dynamic
only applies to LINQ-to-Objects (expression-trees for ORMs etc can't really represent dynamic
queries - MemberExpression
doesn't support it). But here's a way to do it with LINQ-to-Objects. Note that the choice of Hashtable
is due to favorable locking semantics:
using Microsoft.CSharp.RuntimeBinder;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using System.Runtime.CompilerServices;
static class Program
{
private static class AccessorCache
{
private static readonly Hashtable accessors = new Hashtable();
private static readonly Hashtable callSites = new Hashtable();
private static CallSite<Func<CallSite, object, object>> GetCallSiteLocked(
string name)
{
var callSite = (CallSite<Func<CallSite, object, object>>)callSites[name];
if(callSite == null)
{
callSites[name] = callSite = CallSite<Func<CallSite, object, object>>
.Create(Binder.GetMember(
CSharpBinderFlags.None,
name,
typeof(AccessorCache),
new CSharpArgumentInfo[] {
CSharpArgumentInfo.Create(
CSharpArgumentInfoFlags.None,
null)
}));
}
return callSite;
}
internal static Func<dynamic,object> GetAccessor(string name)
{
Func<dynamic, object> accessor = (Func<dynamic, object>)accessors[name];
if (accessor == null)
{
lock (accessors )
{
accessor = (Func<dynamic, object>)accessors[name];
if (accessor == null)
{
if(name.IndexOf('.') >= 0) {
string[] props = name.Split('.');
CallSite<Func<CallSite, object, object>>[] arr
= Array.ConvertAll(props, GetCallSiteLocked);
accessor = target =>
{
object val = (object)target;
for (int i = 0; i < arr.Length; i++)
{
var cs = arr[i];
val = cs.Target(cs, val);
}
return val;
};
} else {
var callSite = GetCallSiteLocked(name);
accessor = target =>
{
return callSite.Target(callSite, (object)target);
};
}
accessors[name] = accessor;
}
}
}
return accessor;
}
}
public static IOrderedEnumerable<dynamic> OrderBy(
this IEnumerable<dynamic> source,
string property)
{
return Enumerable.OrderBy<dynamic, object>(
source,
AccessorCache.GetAccessor(property),
Comparer<object>.Default);
}
public static IOrderedEnumerable<dynamic> OrderByDescending(
this IEnumerable<dynamic> source,
string property)
{
return Enumerable.OrderByDescending<dynamic, object>(
source,
AccessorCache.GetAccessor(property),
Comparer<object>.Default);
}
public static IOrderedEnumerable<dynamic> ThenBy(
this IOrderedEnumerable<dynamic> source,
string property)
{
return Enumerable.ThenBy<dynamic, object>(
source,
AccessorCache.GetAccessor(property),
Comparer<object>.Default);
}
public static IOrderedEnumerable<dynamic> ThenByDescending(
this IOrderedEnumerable<dynamic> source,
string property)
{
return Enumerable.ThenByDescending<dynamic, object>(
source,
AccessorCache.GetAccessor(property),
Comparer<object>.Default);
}
static void Main()
{
dynamic a = new ExpandoObject(),
b = new ExpandoObject(),
c = new ExpandoObject();
a.X = "abc";
b.X = "ghi";
c.X = "def";
dynamic[] data = new[] {
new { Y = a },
new { Y = b },
new { Y = c }
};
var ordered = data.OrderByDescending("Y.X").ToArray();
foreach (var obj in ordered)
{
Console.WriteLine(obj.Y.X);
}
}
}

- 1,717
- 15
- 34

- 1,026,079
- 266
- 2,566
- 2,900
-
119Best damn piece of code I have seen :) Just solved a million problems in my project :) – sajidnizami Nov 20 '08 at 09:37
-
Marc, Do you have the similar extension for LIKE Condition? – Prasad Nov 02 '09 at 03:30
-
@Prasad - `LIKE` is a bit different, but which back end? For LINQ-to-SQL, there is `SqlMethods.Like`: http://msdn.microsoft.com/en-us/library/system.data.linq.sqlclient.sqlmethods.like.aspx; can you add more info what you are looking for? – Marc Gravell Nov 02 '09 at 05:20
-
I am using SQL as backend, i need to do a search operation with dynamic parameter names as like in your OrderBy extension. – Prasad Nov 02 '09 at 05:55
-
Well, you can certainly use `SqlMethods.Like` in a custom expression; it really isn't clear where it breaks down... can you clarify? Perhaps ask as a question? – Marc Gravell Nov 02 '09 at 06:16
-
Thanks Mark, I did in http://stackoverflow.com/questions/1654745/dynamic-linq-like yesterday. Its better if i have a sample on it – Prasad Nov 02 '09 at 06:30
-
3Sounds like lots of folks had success with this code- I can't for the life of me figure out how to apply it! These are extension methods, right? How do I use them?? – Dave Swersky Jan 22 '10 at 18:22
-
4@Dave - you need to start with `IQueryable
`, so if you have something like `List – Marc Gravell Jan 22 '10 at 19:26` (which is `IEnumerable `) you may need to use `AsQueryable()` - for example `var sorted = someList.AsQueryable().OrderBy("Foo.Bar");` -
7Have you seen this... it might help some people... http://stackoverflow.com/questions/557819/strongly-typed-dynamic-linq-sorting/2794039#2794039 its a more strongly typed solution. – anthonyv May 08 '10 at 12:30
-
2Great code ! Do you know any way to add support to the "Count()" extension method ? Calling an extension method is quiet a pain, and I have troubles building an expression with those. I'm trying to add the 'Count()' support for IQueryable
which is coded as extension in the 'Queryable' type. – Mose May 17 '10 at 12:24 -
2@ile - `var ordered = someData.OrderBy("Name");` - or for `IEnumerable
` data, `var ordered = someData.AsQueryable().OrderBy("Name");` – Marc Gravell Jun 03 '10 at 10:01 -
1This be done already with *AsQueryAble().OrderBy().ThenBy()*. There must be something I'm missing. **Edit** I just noticed the above methods are returning *IOrderedQueryable* and the methods I listed are returning *IOrderedEnumerable*. – Chuck Conway Oct 18 '10 at 21:49
-
if use switch which will be faster. reflection vs switch – Nario Apr 29 '11 at 08:41
-
@Nario - context? switch on *what*, vs *what* reflection? Oh, you mean building up with `.OrderBy(x => x.Something)` (times 10 or whatever) - the `switch`, most likely – Marc Gravell Apr 29 '11 at 09:36
-
switch(propertyname) { case "property1": result=datacontex.orderby(x=>x.property1) break; case "property2": result=datacontex.orderby(x=>x.property2) break; } – Nario Apr 29 '11 at 10:18
-
Thanks for this! One improvement I have found is, instead of the Reflection GetMethod()..Invoke() statement, you can build the result direcly in linq: var expression = Expression.Call(typeof(Queryable), methodName, new[] { source.ElementType, expr.Type }, source.Expression, lambda); var result = source.Provider.CreateQuery
(expression); – automagic Jul 13 '11 at 21:14 -
Is it possible to use this approach with an object implementing IDynamicMetaObjectProvider? I'm having issues described in this post: http://stackoverflow.com/questions/11206631/dynamic-sorting-with-a-serializabledynamicobject – BonyT Jun 26 '12 at 11:50
-
@BonyT no, but I've added a "dynamic" approach to your question – Marc Gravell Jun 26 '12 at 12:20
-
@MarcGravell: I post a question in this url : http://stackoverflow.com/questions/12495873/dynamic-sort-in-linq/12495964 . and the problem is when I use your extension methods the result does not sort. what is the problem? – Arian Sep 22 '12 at 12:20
-
Thanks a lot for this code. Same question as Mose: Do you know any way to add support to the "Count()" extension method? – Julien Oct 05 '12 at 14:42
-
Is there a way I can apply a sort by a subcollection? – amhed Oct 14 '12 at 13:31
-
@ahmed depends... What does that *mean*? – Marc Gravell Oct 14 '12 at 19:25
-
3If anyone is interested, I got it to work with `IEnumerable` simply substituting `lambda` with `lambda.Compile()` in the penultimate line, barring the obvious substitutions `IQueryable` > `IEnumerable` and `IOrderedQueryable` with `IOrderedEnumerable`. No wrappers involved – Piddu May 22 '13 at 07:11
-
1Wow, this is ridiculous - a couple of lines of code inflated to forty just to avoid using System.Linq.Dynamic? Is there some kind of advantage to not using it? **Take a look at @Alaa Osta's answer** below (the actual solution to the original question). – MGOwen Jul 13 '13 at 01:11
-
34@MGOwen you seem to misunderstand the nature of code. The 40 lines is the same no matter whether it is 40 lines that you put somewhere in your project, or if those lines come (pre-compiled, or as source) in an external library. It would have been *pretty amazing* if I had linked, in Oct '08 to a library on nuget that has existed since Dec '11 (not least because nuget didn't exist then either), but the fundamental "what it is doing" is the same. Also, you use the phrase "actual solution" as though there is some well-defined agreed single route to every coding question: there is not. – Marc Gravell Jul 13 '13 at 08:15
-
8@MGOwen btw, the external lib is 2296 lines of code (not including AssemblyInfo.cs); which kinda makes the 40 lines here look pretty reasonable – Marc Gravell Jul 13 '13 at 08:18
-
@MarcGravell Ahhh OK, Sorry, didn't notice this answer was so old. I was just pretty confused, as 99% of people who find this question will be. My comment wasn't directed at you, but at them: the hundreds of people finding this question who need the best answer currently available. WRT lines of code, I think most programmers will prefer to use an established library to solve the problem, and if I understand linking correctly, only the code used will be included anyway, right? – MGOwen Jul 15 '13 at 02:03
-
@MGOwen .net doesn't use a linker (except on some AOT frameworks). All the IL will be included, but only the methods that get used will be JIT-ed – Marc Gravell Jul 15 '13 at 06:38
-
Nice, just don't rename any of the properties. – Adam Houldsworth Oct 01 '13 at 10:15
-
@MarcGravell does this sort before or after the sql is run? I also use paging so that I'll only retrieve a few records at the time, but to get the correct records the sorting must be done in the sql statement, not in memory. – Zaphod Jan 13 '14 at 14:20
-
@Zaphod as long as the input is a suitable `IQueryable
`, it is composed into the query without executing anything or doing anything in-memory – Marc Gravell Jan 13 '14 at 15:38 -
Very nice code, it helped me a lot with ordering by column name stored in string. However it doesn't work all that well with interfaces. I mean if you have a IQueryable of an interface class and try to order by a column that isn't part of the interface you'll get an error. Thankfully it's easy enough to fix. Replacing all instances of typeof(T) with source.ElementType will allow ordering by any column of the actual class that is handled within the query. – jahu Jan 30 '14 at 16:30
-
@MarcGravell, In the first snippet you don't need to compute yourself the delegateType of the LambdaExpression. If you don't pass it as first argument it is computed automatically by Expression.Lambda. – Francesco Abbruzzese Dec 29 '16 at 19:17
-
1Very nice... In my extremely basic test this executes in 29 ms vs `System.Linq.Dynamic`'s 148 ms. – shawnseanshaun Jul 27 '18 at 17:27
-
I can't understand even single line from this code, but it works! – Jakub Szułakiewicz May 28 '19 at 07:32
-
I'm using the first part of code and it works very cool. But after changing the project to .net Core 3.0 the nullable-warnings are driving me crazy. Could you please update the code? – Henning Oct 14 '19 at 08:35
-
@Henning (places tongue in cheek) - sure! `#nullable disable` – Marc Gravell Oct 14 '19 at 09:09
-
@MarcGravell Hey master, do I need to escape the input to prevent injections? – Nicholas Dec 02 '19 at 15:55
-
1@Nicholas no, the expression-tree parser/SQL generator layer deals with that, as parameters – Marc Gravell Dec 02 '19 at 16:18
Too easy without any complication:
- Add
using System.Linq.Dynamic;
at the top. - Use
vehicles = vehicles.AsQueryable().OrderBy("Make ASC, Year DESC").ToList();
Edit: to save some time, the System.Linq.Dynamic.Core (System.Linq.Dynamic is deprecated) assembly is not part of the framework, but can be installed from nuget: System.Linq.Dynamic.Core
-
13
-
1
-
40The accepted answer may have been the correct answer in 2008 but currently this is the easiest, most correct answer now. – EL MOJO Oct 24 '14 at 15:33
-
1This is really good and simple handling, so much complexity internally, loved it – Mrinal Kamboj May 28 '16 at 14:25
-
1Is it possible to sort by a nested property?, for example: vehicles = vehicles.AsQueryable().OrderBy("Status.Label ASC, Year DESC").ToList(); – Faly Jul 19 '17 at 09:35
-
-
18For the people in the "future", if you are using dotnet core, use this: https://www.nuget.org/packages/System.Linq.Dynamic.Core – Rafael Merlin Nov 01 '17 at 02:08
-
2For anybody looking through this as I did for the same solution - this is working for sorting on "Nested" objects, i.e. `vehicles.AsQueryable().OrderBy("Tire.Size").ToList();`, where `Tire` is a object that belongs to `Vehicle`. – neilsimp1 Jan 11 '19 at 13:42
-
6@RafaelMerlin Also the namespace is now System.Linq.Dynamic.Core – Edwin Stoteler Jun 09 '20 at 10:53
-
nuget.org/packages/System.Linq.Dynamic.Core – is this free or licensed version? – Raj Jul 28 '20 at 04:53
-
How would you sort on included/joined columns ? Is there a way to avoid precising the joined table like @neilsimp1 mentionned ? I'd like something like : `vehicles.Include(v => v.Tire).AsQueryable().OrderBy("Size ASC").ToList()` – Axel Samyn Oct 21 '22 at 09:45
Just stumbled across this question.
Using Marc's ApplyOrder implementation from above, I slapped together an Extension method that handles SQL-like strings like:
list.OrderBy("MyProperty DESC, MyOtherProperty ASC");
Details can be found here: http://aonnull.blogspot.com/2010/08/dynamic-sql-like-linq-orderby-extension.html

- 867
- 8
- 7
-
1Great stuff, just add a modification as follows to make the property name case insensitive: PropertyInfo pi = type.GetProperty(prop,BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase); – Mrinal Kamboj May 29 '16 at 07:47
I guess it would work to use reflection to get whatever property you want to sort on:
IEnumerable<T> myEnumerables
var query=from enumerable in myenumerables
where some criteria
orderby GetPropertyValue(enumerable,"SomeProperty")
select enumerable
private static object GetPropertyValue(object obj, string property)
{
System.Reflection.PropertyInfo propertyInfo=obj.GetType().GetProperty(property);
return propertyInfo.GetValue(obj, null);
}
Note that using reflection is considerably slower than accessing the property directly, so the performance would have to be investigated.

- 6,097
- 3
- 29
- 23
-
does this even work? orderby does not want a value but a selector lamba/delegate (Func
keySelector).. – Davy Landman Oct 24 '08 at 12:58 -
2I did try this example before posting it, and yes, it does work. – Kjetil Watnedal Oct 28 '08 at 07:22
-
3+1 This is exactly what I was looking for! This will work great for simple page sorting issues. – Andrew Siemer Apr 19 '10 at 04:08
-
This didn't work for me. Am I missing something? What should "SomeProperty" be. I tried giving the property name as well as property.GetType(). I have IQueryable<> and not IEnumerable<> – Rashmi Pandit Jul 23 '10 at 05:59
-
GetPropertyValue mehotod will be executed for all elements, it's bad solution. – Alex Shkor Feb 14 '12 at 16:25
-
2@Alex Shkor: How are you supposed to sort the elements without looking at all the elements? However, there are better solutions in other answers. – Kjetil Watnedal Feb 15 '12 at 12:58
Just building on what others have said. I found that the following works quite well.
public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> input, string queryString)
{
if (string.IsNullOrEmpty(queryString))
return input;
int i = 0;
foreach (string propname in queryString.Split(','))
{
var subContent = propname.Split('|');
if (Convert.ToInt32(subContent[1].Trim()) == 0)
{
if (i == 0)
input = input.OrderBy(x => GetPropertyValue(x, subContent[0].Trim()));
else
input = ((IOrderedEnumerable<T>)input).ThenBy(x => GetPropertyValue(x, subContent[0].Trim()));
}
else
{
if (i == 0)
input = input.OrderByDescending(x => GetPropertyValue(x, subContent[0].Trim()));
else
input = ((IOrderedEnumerable<T>)input).ThenByDescending(x => GetPropertyValue(x, subContent[0].Trim()));
}
i++;
}
return input;
}
I was trying to do this but having problems with Kjetil Watnedal's solution because I don't use the inline linq syntax - I prefer method-style syntax. My specific problem was in trying to do dynamic sorting using a custom IComparer
.
My solution ended up like this:
Given an IQueryable query like so:
List<DATA__Security__Team> teams = TeamManager.GetTeams();
var query = teams.Where(team => team.ID < 10).AsQueryable();
And given a run-time sort field argument:
string SortField; // Set at run-time to "Name"
The dynamic OrderBy looks like so:
query = query.OrderBy(item => item.GetReflectedPropertyValue(SortField));
And that's using a little helper method called GetReflectedPropertyValue():
public static string GetReflectedPropertyValue(this object subject, string field)
{
object reflectedValue = subject.GetType().GetProperty(field).GetValue(subject, null);
return reflectedValue != null ? reflectedValue.ToString() : "";
}
One last thing - I mentioned that I wanted the OrderBy
to use custom IComparer
- because I wanted to do Natural sorting.
To do that, I just alter the OrderBy
to:
query = query.OrderBy(item => item.GetReflectedPropertyValue(SortField), new NaturalSortComparer<string>());
See this post for the code for NaturalSortComparer()
.

- 37,241
- 25
- 195
- 267

- 9,217
- 3
- 47
- 57
After a lot of searching this worked for me:
public static IEnumerable<TEntity> OrderBy<TEntity>(this IEnumerable<TEntity> source,
string orderByProperty, bool desc)
{
string command = desc ? "OrderByDescending" : "OrderBy";
var type = typeof(TEntity);
var property = type.GetProperty(orderByProperty);
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExpression = Expression.Lambda(propertyAccess, parameter);
var resultExpression = Expression.Call(typeof(Queryable), command,
new[] { type, property.PropertyType },
source.AsQueryable().Expression,
Expression.Quote(orderByExpression));
return source.AsQueryable().Provider.CreateQuery<TEntity>(resultExpression);
}
I've stumble this question looking for Linq multiple orderby clauses and maybe this was what the author was looking for
Here's how to do that:
var query = pets.OrderBy(pet => pet.Name).ThenByDescending(pet => pet.Age);

- 101,809
- 122
- 424
- 632

- 6,983
- 9
- 41
- 53
-
6+1 canceled the down-vote due to lack of explanation. I also think the author might have been interested in multiple order-bys. Even if dynamic *was* the key word, no reason to down-vote. – Jason Kleban May 25 '10 at 18:51
Use dynamic linq
just add using System.Linq.Dynamic;
And use it like this to order all your columns:
string sortTypeStr = "ASC"; // or DESC
string SortColumnName = "Age"; // Your column name
query = query.OrderBy($"{SortColumnName} {sortTypeStr}");

- 3,754
- 4
- 33
- 41
First Install Dynamic Tools --> NuGet Package Manager --> Package Manager Console
install-package System.Linq.Dynamic
Add Namespace using System.Linq.Dynamic;
Now you can use OrderBy("Name, Age DESC")

- 400
- 1
- 6
- 14
-
How can I use it with inner property sorting - like OrderBy("Branch.BranchName","Descending") – devC May 23 '19 at 11:08
-
This works for me. Perhaps because the question is 10 years old, and this easier method only came later. – kosherjellyfish Jul 12 '19 at 06:49
You could add it:
public static IEnumerable<T> OrderBy( this IEnumerable<T> input, string queryString) {
//parse the string into property names
//Use reflection to get and sort by properties
//something like
foreach( string propname in queryString.Split(','))
input.OrderBy( x => GetPropertyValue( x, propname ) );
// I used Kjetil Watnedal's reflection example
}
The GetPropertyValue
function is from Kjetil Watnedal's answer
The issue would be why? Any such sort would throw exceptions at run-time, rather than compile time (like D2VIANT's answer).
If you're dealing with Linq to Sql and the orderby is an expression tree it will be converted into SQL for execution anyway.
-
GetPropertyValue mehotod will be executed for all elements, it's bad solution. – Alex Shkor Feb 14 '12 at 16:27
-
2
Here's something else I found interesting. If your source is a DataTable, you can use dynamic sorting without using Dynamic Linq
DataTable orders = dataSet.Tables["SalesOrderHeader"];
EnumerableRowCollection<DataRow> query = from order in orders.AsEnumerable()
orderby order.Field<DateTime>("OrderDate")
select order;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;
reference: http://msdn.microsoft.com/en-us/library/bb669083.aspx (Using DataSetExtensions)
Here is one more way to do it by converting it to a DataView:
DataTable contacts = dataSet.Tables["Contact"];
DataView view = contacts.AsDataView();
view.Sort = "LastName desc, FirstName asc";
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();

- 3,092
- 4
- 36
- 36
You can convert the IEnumerable to IQueryable.
items = items.AsQueryable().OrderBy("Name ASC");

- 1,402
- 15
- 10
You can use this:
public List<Book> Books(string orderField, bool desc, int skip, int take)
{
var propertyInfo = typeof(Book).GetProperty(orderField);
return _context.Books
.Where(...)
.OrderBy(p => !desc ? propertyInfo.GetValue(p, null) : 0)
.ThenByDescending(p => desc ? propertyInfo.GetValue(p, null) : 0)
.Skip(skip)
.Take(take)
.ToList();
}

- 121
- 7
-
A couple of years later and I stumble upon this; this worked for me, like a dream. I have dynamic sorting on 1 to 3 properties, and this works like a dream. Easy to implement and hassle free. – Bazïnga Mar 22 '20 at 06:44
-
Love this answer, but how can I make this work if I need to sort by a property of a child class? – RoLYroLLs Jul 20 '20 at 21:17
Thanks to Maarten (Query a collection using PropertyInfo object in LINQ) I got this solution:
myList.OrderByDescending(x => myPropertyInfo.GetValue(x, null)).ToList();
In my case I was working on a "ColumnHeaderMouseClick" (WindowsForm) so just found the specific Column pressed and its correspondent PropertyInfo:
foreach (PropertyInfo column in (new Process()).GetType().GetProperties())
{
if (column.Name == dgvProcessList.Columns[e.ColumnIndex].Name)
{}
}
OR
PropertyInfo column = (new Process()).GetType().GetProperties().Where(x => x.Name == dgvProcessList.Columns[e.ColumnIndex].Name).First();
(be sure to have your column Names matching the object Properties)
Cheers

- 1
- 1

- 281
- 3
- 12
This answer is a response to the comments that need an example for the solution provided by @John Sheehan - Runscope
Please provide an example for the rest of us.
in DAL (Data Access Layer),
The IEnumerable version:
public IEnumerable<Order> GetOrders()
{
// i use Dapper to return IEnumerable<T> using Query<T>
//.. do stuff
return orders // IEnumerable<Order>
}
The IQueryable version
public IQueryable<Order> GetOrdersAsQuerable()
{
IEnumerable<Order> qry= GetOrders();
// use the built-in extension method AsQueryable in System.Linq namespace
return qry.AsQueryable();
}
Now you can use the IQueryable version to bind, for example GridView in Asp.net and benefit for sorting (you can't sort using IEnumerable version)
I used Dapper as ORM and build IQueryable version and utilized sorting in GridView in asp.net so easy.
An alternate solution uses the following class/interface. It's not truly dynamic, but it works.
public interface IID
{
int ID
{
get; set;
}
}
public static class Utils
{
public static int GetID<T>(ObjectQuery<T> items) where T:EntityObject, IID
{
if (items.Count() == 0) return 1;
return items.OrderByDescending(u => u.ID).FirstOrDefault().ID + 1;
}
}

- 1,104
- 2
- 13
- 30
You can define a dictionary from string to Func<> like this :
Dictionary<string, Func<Item, object>> SortParameters = new Dictionary<string, Func<Item, object>>()
{
{"Rank", x => x.Rank}
};
And use it like this :
yourList.OrderBy(SortParameters["Rank"]);
In this case you can dynamically sort by string.

- 1,797
- 2
- 7
- 21
-
1Nice! Really simple option for those of who can't use Dynamic Linq lib. – Ash8087 Sep 15 '22 at 21:08
-
1
you can do it like this for multiple order by
IOrderedEnumerable<JToken> sort;
if (query.OrderBys[0].IsDESC)
{
sort = jarry.OrderByDescending(r => (string)r[query.OrderBys[0].Key]);
}
else
{
sort = jarry.OrderBy(r =>
(string) r[query.OrderBys[0].Key]);
}
foreach (var item in query.OrderBys.Skip(1))
{
if (item.IsDESC)
{
sort = sort.ThenByDescending(r => (string)r[item.Key]);
}
else
{
sort = sort.ThenBy(r => (string)r[item.Key]);
}
}

- 39,551
- 56
- 175
- 291

- 101
- 1
- 3
Convert List to IEnumerable or Iquerable, add using System.LINQ.Dynamic namespace, then u can mention the property names in comma seperated string to OrderBy Method which comes by default from System.LINQ.Dynamic.

- 2,949
- 4
- 43
- 75
I am able to do this with the code below. No need write long and complex code.
protected void sort_array(string field_name, string asc_desc)
{
objArrayList= Sort(objArrayList, field_name, asc_desc);
}
protected List<ArrayType> Sort(List<ArrayType> input, string property, string asc_desc)
{
if (asc_desc == "ASC")
{
return input.OrderBy(p => p.GetType()
.GetProperty(property)
.GetValue(p, null)).ToList();
}
else
{
return input.OrderByDescending(p => p.GetType()
.GetProperty(property)
.GetValue(p, null)).ToList();
}
}

- 1,393
- 1
- 16
- 26
If you are using Specification (such as Ardalis Specification)
using Microsoft.EntityFrameworkCore;
namespace TestExtensions;
public static class IQueryableExtensions
{
public static void ApplyOrder<T>(ISpecificationBuilder<T> query, string propertyName, bool ascendingOrder)
{
if (ascendingOrder)
query.OrderBy(T => EF.Property<object>(T!, propertyName));
else
query.OrderByDescending(T => EF.Property<object>(T!, propertyName));
}
}

- 2,732
- 2
- 21
- 24
-
Because this doesn't answer the question: "Is there any way to get this functionality on `IEnumerable
`?". Questions on Stack Overflow are not answered by offering alternatives to what people are doing because that could go on and on. We only do that if the approach in the question is clearly hopeless. – Gert Arnold Jan 26 '23 at 09:45 -
I answered because I had the same problem, and I added if to the answer... Though, thanks for clearing why you down-voted. – Joseph Wambura Jan 26 '23 at 12:21
With Net6 and EF
.AsQueryable().OrderBy((ColumnOrder.Column, ColumnOrder.Dir));

- 124
- 1
- 2
var result1 = lst.OrderBy(a=>a.Name);// for ascending order.
var result1 = lst.OrderByDescending(a=>a.Name);// for desc order.

- 178
- 1
- 5