我正在使用下面的方法来查询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();
}
}
现在我想创建动态Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>>
表达式来订购我的数据。
我只知道字段名称为字符串,顺序类型(升序,降序)为字符串(asc,desc)
答案 0 :(得分:11)
最后我可以写出我想要的方法。
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();
}
此方法有两个参数,第一个是字段名,另一个是asc或desc。 方法的结果可以直接用于IQueryable对象。
感谢您的帮助
答案 1 :(得分:2)
我不确定您想要完成的是什么,但我已经更改了您的代码并添加了一些示例来演示它是如何工作的。
这是一个简单的控制台应用程序,其中包含dummyText作为列表。可查询方法允许您根据需要使用过滤器和排序表达式。我希望它有所帮助
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();
}
}
}
答案 2 :(得分:2)
这对派对来说已经很晚了,但正确的答案位于https://stackoverflow.com/a/10935223/14275
的另一个问题上var students = repository.Get(x => x.FirstName = "Bob",q => q.OrderBy(s => s.LastName));