Dynamic Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> Expression

匿名 (未验证) 提交于 2019-12-03 03:09:01

问题:

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)

回答1:

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



回答2:

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();         }        }  } 


回答3:

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)); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!