我希望将一个或多个排序子句的任意序列(通过动态linq使用表达式而不是字符串声明)附加到IQueryable。怎么可能这样做?
这是问题的关键所在:
private IOrderedQueryable<TProject> Demo<TSource, TProject>(
IQueryable<TSource> query,
Expression<Func<TSource, TProject>> project,
Expression<Func<IQueryable<TProject>, IOrderedQueryable<TProject>>> order
) {
var projection = query.Select(project);
//??? How to combine project and order as an expression tree
var orderedProjection = order.Compile()(projection);
//??? rather than a compiled delegate (as shown here)
return orderedProjection;
}
更多上下文(由khellang指出不会编译):
private class ProjectOrder<TProjection> {
public Expression<Func<Part, TProjection>> Projection { get; set; }
public Expression<Func<IQueryable<TProjection>, IOrderedQueryable<TProjection>>> Ordering { get; set; }
}
private class PartFilters {
public string Text { get; set; }
public string[] PartNumbers { get; set; }
public int[] PartTypes { get; set; }
//....
}
private IOrderedQueryable<TProjection> Fetch<TProjection>(ProjectOrder<TProjection> projectOrder, PartFilters filters) {
var baseQuery = _db.Part_Parts;
//append where predicates to baseQuery based on filters
var projection = baseQuery.Select(projectOrder.Projection);
//??? How to combine projection and ordering as
var orderedProjection = projectOrder.Ordering.Compile()(projection);
//??? an expression tree rather than a compiled delegate
return orderedProjection;
}
private void TestFetch(PartFilters filters) {
Expression<Func<Part, PartDescription>> projection = _ => new PartDescription() {
PartNumber = _.PartNumber,
Description = _.Description
};
//Arbitrary sorting expression, multiple clauses, could use base classes or joined entities
//via navigation properties
Expression<Func<IQueryable<PartDescription>, IOrderedQueryable<PartDescription>>> order =
q => q.OrderBy(_ => _.PartNumber.Length).ThenBy(_ => _.PartNumber);
var projectOrder = new ProjectOrder<PartDescription>() {
Projection = projection,
Ordering = order
};
Fetch<PartDescription>(projectOrder, filters);
}
答案 0 :(得分:1)
第三个参数根本没有理由成为表达式。它可以只是一个普通的代表。
这里的重点是执行order
实际上并没有执行排序。执行order
操纵查询的表达式。您不需要Expression
来表示如何操纵Expression
对象。你可以这样做。
private IOrderedQueryable<TProject> Demo<TSource, TProject>(
IQueryable<TSource> query,
Expression<Func<TSource, TProject>> projection,
Func<IQueryable<TProject>, IOrderedQueryable<TProject>> order)
{
return order(query.Select(projection));
}
瞧,你有一个方法可以根据投影和排序来构建查询。