添加对 Linq 表达式的方法调用,同时保留完整表达式
如何在保留 linq 表达式的同时扩展它?我已经简化了很多(以避免粘贴页面) - 例如,我使用 Queryable 而不是 Enumerable,但是这个解决方案就足够了,最终我需要将其保留为表达式,同时添加方法调用。
例如,
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};
Expression<Func<IEnumerable<Person>, IEnumerable<Person>>> filterExp
= list => list.Take(2);
Expression<Func<Person, int>> sortExp = l => l.Age;
MethodCallExpression orderByCallExpression = Expression.Call(
typeof (Enumerable),
"OrderByDescending",
new Type[] {typeof (Person), typeof (int)},
filterExp.Parameters[0],
sortExp);
var combinedExpression = Expression.Lambda<Func<IEnumerable<Person>, IEnumerable<Person>>>
(filterExp.AddMethodCall(orderByCallExpression)); // made up AddMethodCall but you get the idea
过去几个小时我搜索了几十个SO帖子,但我似乎无法弄清楚这一点, 如果我编译filterExp,但不保留表达式和最终结果表达式,我就可以做到这一点。
How I do extend an linq expression whilst keeping it an expression? I've simplified this quite a bit (to avoid pasting pages) - .e.g I working with Queryable rather than Enumerable, but the solution for this will suffice, ultimately I need to keep it as an expression whilst adding a method call to it.
For exampleL
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};
Expression<Func<IEnumerable<Person>, IEnumerable<Person>>> filterExp
= list => list.Take(2);
Expression<Func<Person, int>> sortExp = l => l.Age;
MethodCallExpression orderByCallExpression = Expression.Call(
typeof (Enumerable),
"OrderByDescending",
new Type[] {typeof (Person), typeof (int)},
filterExp.Parameters[0],
sortExp);
var combinedExpression = Expression.Lambda<Func<IEnumerable<Person>, IEnumerable<Person>>>
(filterExp.AddMethodCall(orderByCallExpression)); // made up AddMethodCall but you get the idea
I've searched dozens of SO posts for the past few hours and I can't seem to figure this out,
I can do it if I compile filterExp but not without keeping both expressions and end result an expression.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,您不需要将所有内容都切换到
IEnumerable
:AsQueryable()
将允许您将测试集合与表达式树一起使用:您有了一个良好的开端,您只需要改变您正在使用的内容:
我们使用
filterExp.Body
提取list.Take(2)
作为OrderByDescending
的第一个参数code>,然后将filterExp
参数移至 lambda 表达式。我想这就是您的预期用途?
First, you don't need to switch everything to
IEnumerable
:AsQueryable()
will let you use your test collection with expression trees:You were off to a good start, you just need to shift around what you're using where:
We use
filterExp.Body
to extractlist.Take(2)
as the first parameter toOrderByDescending
, then move thefilterExp
parameter to the lambda expression.I assume this is your intended usage?