可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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));