Note that there are some explanatory texts on larger screens.

plurals
  1. PODynamic LINQ OrderBy + Method Count
    text
    copied!<p>I'm displaying a table of objects <strong>Company</strong> in a webpage and I am using a Dynamic Linq OrderBy to sort them on each property. I'm using this code <a href="https://stackoverflow.com/a/233505/265122">https://stackoverflow.com/a/233505/265122</a></p> <pre><code>public static IOrderedQueryable&lt;T&gt; OrderBy&lt;T&gt;(this IQueryable&lt;T&gt; source, string property) { return ApplyOrder&lt;T&gt;(source, property, "OrderBy"); } public static IOrderedQueryable&lt;T&gt; OrderByDescending&lt;T&gt;(this IQueryable&lt;T&gt; source, string property) { return ApplyOrder&lt;T&gt;(source, property, "OrderByDescending"); } public static IOrderedQueryable&lt;T&gt; ThenBy&lt;T&gt;(this IOrderedQueryable&lt;T&gt; source, string property) { return ApplyOrder&lt;T&gt;(source, property, "ThenBy"); } public static IOrderedQueryable&lt;T&gt; ThenByDescending&lt;T&gt;(this IOrderedQueryable&lt;T&gt; source, string property) { return ApplyOrder&lt;T&gt;(source, property, "ThenByDescending"); } static IOrderedQueryable&lt;T&gt; ApplyOrder&lt;T&gt;(IQueryable&lt;T&gt; 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&lt;,&gt;).MakeGenericType(typeof(T), type); LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg); object result = typeof(Queryable).GetMethods().Single( method =&gt; method.Name == methodName &amp;&amp; method.IsGenericMethodDefinition &amp;&amp; method.GetGenericArguments().Length == 2 &amp;&amp; method.GetParameters().Length == 2) .MakeGenericMethod(typeof(T), type) .Invoke(null, new object[] {source, lambda}); return (IOrderedQueryable&lt;T&gt;)result; } </code></pre> <p>It's great but I would also like to sort the companies on the number of employees.</p> <p>Like this : <strong>query.OrderBy("Employees.Count")</strong></p> <p>I tried to call to the Count method dynamically without any success so far.</p> <p>I modified the code like this :</p> <pre><code>foreach(string prop in props) { if (prop == "Count") { var countMethod = (typeof(Enumerable)).GetMethods().First(m =&gt; m.Name == "Count").MakeGenericMethod(type); expr = Expression.Call(countMethod, expr); break; } // Use reflection (not ComponentModel) to mirror LINQ. PropertyInfo pi = type.GetProperty(prop); expr = Expression.Property(expr, pi); type = pi.PropertyType; } </code></pre> <p>But I have an exception on the <code>expr = Expression.Call(countMethod, expr);</code></p> <p>The exception is:</p> <pre><code>ArgumentException Expression of type 'System.Collections.Generic.ICollection`1[Employee]' cannot be used for parameter of type 'System.Collections.Generic.IEnumerable`1[System.Collections.Generic.ICollection`1 [Employee]]' of method 'Int32 Count[ICollection`1] System.Collections.Generic.IEnumerable`1[System.Collections.Generic.ICollection`1 Employee]])' </code></pre> <p>Any idea on how to achieve that?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload