Reputation: 487
I had followed this link to create dynamic orderby clause in linq queries using Expression trees.
But later I came across a scenario where I had to sort the values of a column with keeping the null value in mind as my database column allows null i.e. All the non-null values should be sorted ascending and then null values should be followed.
So I followed this link to modify my dynamic LINQ code to handle the above scenario. i.e. I tried to add HasValue
call in my OrderBy()
call. But it started to fail with below error.
No generic method 'OrderBy' on type 'System.Linq.Queryable' is compatible with the supplied type arguments and arguments. No type arguments should be provided if the method is non-generic.
The argument that causes Expression.Call()
to fail:
p.IsProcessStarted.HasValue
Below is the code that I am using:
public static class ExtensionMethods
{
public static IQueryable<TEntity> OrderBy<TEntity>(
this IQueryable<TEntity> source, string orderByProperty, bool desc)
{
string command = desc ? "OrderByDescending" : "OrderBy";
var type = typeof(TEntity);
var property = type.GetProperty(orderByProperty);
var propertyType = property.PropertyType;
bool isNullable = propertyType.IsGenericType
&& propertyType.GetGenericTypeDefinition() == typeof(Nullable<>);
var parameter
= Expression.Parameter(type, "p");
MemberExpression propertyAccess
= Expression.MakeMemberAccess(parameter, property);
MemberExpression hasValue
= Expression.Property(propertyAccess, "HasValue");
LambdaExpression orderByExpression
= Expression.Lambda(hasValue, parameter);
MethodCallExpression resultExpression
= Expression.Call(typeof(Queryable), command,
new Type[] { type, property.PropertyType }, source.Expression,
Expression.Quote(orderByExpression));
return source.Provider.CreateQuery<TEntity>(resultExpression);
}
}
This is how I am calling the above extension method:
var res = myQuery.OrderBy("IsProcessStarted", true)
And the expression I want to build is .OrderBy(p>=p.IsProcessStarted.HasValue)
Upvotes: 0
Views: 519
Reputation: 39025
Your code is trying to implement this OrderBy
:
.OrderBy(p => p.HasValue)
This expression returns a bool
. So, to make it work, you must specify the type correctly in the Expression.Call
invocation, like this:
MethodCallExpression resultExpression
= Expression.Call(typeof(Queryable), command,
new Type[] { type, typeof(bool) }, // Expression<Func<type, bool>>
source.Expression,
Expression.Quote(orderByExpression));
NOTE: I don't know if this is what you want, but the code compiles and runs correctly if you implement it like this. However, as I asked in the comment, you shoul show which lambda you want to implement. You should also modify your code to support the scenarios of nullable and not nullable properties. You are checking this, with isNullable
, but you're not using it anywhere
Upvotes: 1