I am using patterns mentioned here http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
And i am using method below to query EF
public virtual IEnumerable<TEntity> Get(
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
string includeProperties = "")
{
IQueryable<TEntity> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
foreach (var includeProperty in includeProperties.Split
(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
{
query = query.Include(includeProperty);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
Now i want to create dynamic Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>
expression to order my data.
I know only field name as string and order type (ascending, descending) as string (asc, desc)
finally i could write the method i want.
public static Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> GetOrderBy(string orderColumn, string orderType) {
Type typeQueryable = typeof(IQueryable<TEntity>);
ParameterExpression argQueryable = Expression.Parameter(typeQueryable, "p");
var outerExpression = Expression.Lambda(argQueryable, argQueryable);
string[] props = orderColumn.Split('.');
IQueryable<TEntity> query = new List<TEntity>().AsQueryable<TEntity>();
Type type = typeof(TEntity);
ParameterExpression arg = Expression.Parameter(type, "x");
Expression expr = arg;
foreach(string prop in props) {
PropertyInfo pi = type.GetProperty(prop, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
expr = Expression.Property(expr, pi);
type = pi.PropertyType;
}
LambdaExpression lambda = Expression.Lambda(expr, arg);
string methodName = orderType == "asc" ? "OrderBy" : "OrderByDescending";
MethodCallExpression resultExp =
Expression.Call(typeof(Queryable), methodName, new Type[] { typeof(TEntity), type }, outerExpression.Body, Expression.Quote(lambda));
var finalLambda = Expression.Lambda(resultExp, argQueryable);
return (Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>)finalLambda.Compile();
}
This method takes two parameters, first one field name other one is asc or desc. Result of method can be used directly with IQueryable object.
Thanks for your helps
This is very late to the party but the correct answer is located on another question at https://stackoverflow.com/a/10935223/14275
var students = repository.Get(x => x.FirstName = "Bob",q => q.OrderBy(s => s.LastName));
I am not sure what exactly you want to accomplish, but I had changed your code and add some example to demonstrate how does it work.
This is a simple console app, which has dummyText as list. Queryable method enables to use filter and sort expression as you want. I hope it helps
class Program
{
private List<string> _dummyText = new List<string>(){ "Arda",
"Araba",
"Antartika",
"Balon"};
static void Main(string[] args)
{
Program p = new Program();
List<string> result = p.Get(s => s.StartsWith("A"), orderBy: q => q.OrderBy(d => d.Length)).ToList();
Console.ReadLine();
}
public virtual IEnumerable<string> Get(
Expression<Func<string, bool>> filter = null,
Func<IQueryable<string>, IOrderedQueryable<string>> orderBy = null)
{
IQueryable<string> query = _dummyText.AsQueryable();
if (filter != null)
{
query = query.Where(filter);
}
if (orderBy != null)
{
return orderBy(query).ToList();
}
else
{
return query.ToList();
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With