First, you don't need to switch everything to IEnumerable
: AsQueryable()
will let you use your test collection with expression trees:
var p1 = new Person() { Name = "RDA1", Age = 27 };
var p2 = new Person() { Name = "RDA2", Age = 28 };
var p3 = new Person() { Name = "RDA3", Age = 29 };
var people = new[] { p1, p2, p3 }.AsQueryable();
You were off to a good start, you just need to shift around what you're using where:
Expression<Func<IQueryable<Person>, IQueryable<Person>>> filterExp
= list => list.Take(2);
Expression<Func<Person, int>> sortExp = l => l.Age;
MethodCallExpression orderByCallExpression = Expression.Call(
typeof(Queryable),
"OrderByDescending",
new Type[] { typeof(Person), typeof(int) },
filterExp.Body,
sortExp);
var combinedExpression =
Expression.Lambda<Func<IQueryable<Person>, IQueryable<Person>>>(
orderByCallExpression, filterExp.Parameters[0]);
We use filterExp.Body
to extract list.Take(2)
as the first parameter to OrderByDescending
, then move the filterExp
parameter to the lambda expression.
I assume this is your intended usage?
var compiled = combinedExpression.Compile();
var res = compiled(people);
foreach (var r in res)
{
// Do something
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…