Error is
LINQ to Entities does not recognize the method 'System.Object
GetValue(System.Object, System.Object[])' method, and this method
cannot be translated into a store expression.
My code is
public static GridResult GetAllUsers(int count, int tblsize,string sortcreteria)
{
using (UserEntities entity = new UserEntities())
{
var data = entity.User_Details.Take(count)
.OrderBy(i =>.GetType().GetProperty(sortcreteria).GetValue(i,null))
.Skip(tblsize).ToList();
result.DataSource = data;
result.Count = entity.User_Details.Count();
}
return result;
}
How to sort with property name as string?
Just add the following extension to your code and you're good to go:
using System.Linq;
using System.Linq.Expressions;
using System;
namespace SomeNameSpace
{
public static class SomeExtensionClass
{
public static IQueryable<T> OrderByField<T>(this IQueryable<T> q, string SortField, bool Ascending)
{
var param = Expression.Parameter(typeof(T), "p");
var prop = Expression.Property(param, SortField);
var exp = Expression.Lambda(prop, param);
string method = Ascending ? "OrderBy" : "OrderByDescending";
Type[] types = new Type[] { q.ElementType, exp.Body.Type };
var mce = Expression.Call(typeof(Queryable), method, types, q.Expression, exp);
return q.Provider.CreateQuery<T>(mce);
}
}
}
Usage:
.OrderByField(sortcriteria, true)
Edit:
For support for the ThenBy
method however the following methods returning an IOrderedQueryable
should take care of it all:
public static class SomeExtensionClass
{
private static IOrderedQueryable<T> OrderingHelper<T>(IQueryable<T> source, string propertyName, bool descending, bool anotherLevel)
{
var param = Expression.Parameter(typeof(T), "p");
var property = Expression.PropertyOrField(param, propertyName);
var sort = Expression.Lambda(property, param);
var call = Expression.Call(
typeof(Queryable),
(!anotherLevel ? "OrderBy" : "ThenBy") + (descending ? "Descending" : string.Empty),
new[] { typeof(T), property.Type },
source.Expression,
Expression.Quote(sort));
return (IOrderedQueryable<T>)source.Provider.CreateQuery<T>(call);
}
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName)
{
return OrderingHelper(source, propertyName, false, false);
}
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string propertyName, bool descending)
{
return OrderingHelper(source, propertyName, descending, false);
}
public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string propertyName)
{
return OrderingHelper(source, propertyName, false, true);
}
public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string propertyName, bool descending)
{
return OrderingHelper(source, propertyName, descending, true);
}
}
You could try to do this using the (somewhat old) Dynamic LINQ library:
var data = entity.User_Details
.Take(count)
.OrderBy(sortcriteria)
.Skip(tblsize)
.ToList();
Alternatively, you can still sort the sequence using your original query by moving the objects into memory first, since the LINQ to Entities provider can't translate calls to the Reflection API into SQL:
var data = entity.User_Details
.Take(count)
.Skip(tblsize)
.AsEnumerable()
.OrderBy(i => i.GetType().GetProperty(sortcriteria).GetValue(i, null))
You will probably need to use Expression Trees
to construct the Linq statement OrderBy(x => x.SomeProperty)
.
Create an OrderBy Expression for LINQ/Lambda
Create LINQ to entities OrderBy expression on the fly