[英]Converting 2 argument Lambda expression to 1 argument Lambda expression (specifying one argument)
I have expression 我有表情
Expression<Func<Car, Driver, bool>> CanBeDrivenBy =
(car, driver) => car.Category == 'B' && driver.Age > 18;
and I want to get cars which can be driven by some driver 我想得到一些可以由一些司机驾驶的汽车
IQueryable<Cars> cars = ...;
Driver driver = ...;
cars.Where(CanBeDrivenBy); // Fail, expecting Expression<Func<Car, bool>>
So I need to convert Expression<Func<Car, Driver, bool>>
to Expression<Func<Car, bool>>
(specify driver) 所以我需要将
Expression<Func<Car, Driver, bool>>
为Expression<Func<Car, bool>>
(指定驱动程序)
Yes I can use 是的,我可以使用
cars.Where(c => c.Category == 'B' && driver.Age > 18);
but I need solution with expression which can be changed dynamicly. 但我需要能够动态改变的表达式解决方案。 And I need to pass Expression (using entity framework)
我需要传递Expression(使用实体框架)
This WORKS 这个工作
I wrote this function to reduce number of arguments from 2 to 1 by specifying the second argument. 我写了这个函数,通过指定第二个参数来减少从2到1的参数数量。
public static Expression<Func<T1, TResult>> Bind2nd<T1, T2, TResult>(Expression<Func<T1, T2, TResult>> source, T2 argument)
{
Expression arg2 = Expression.Constant(argument, typeof(T2));
var arg1 = Expression.Parameter(typeof(T1));
return Expression.Lambda<Func<T1, TResult>>(Expression.Invoke(source, arg1, arg2), arg1);
}
Usage: 用法:
IQueryable<Car> cars = ...;
Driver driver = ...;
cars.Where(Bind2nd(CanBeDrivenBy, driver));
arg1
is temporary storage between calls. arg1
是调用之间的临时存储。
Is there any system equivalent function? 有任何系统等效功能吗?
you can reuse modified version of source expressions body 您可以重用源表达式体的修改版本
using System;
using System.Linq.Expressions;
public class Program
{
public static Expression<Func<T1, TResult>> Bind2nd<T1, T2, TResult>(Expression<Func<T1, T2, TResult>> source, T2 argument)
{
Expression arg2 = Expression.Constant(argument, typeof (T2));
Expression newBody = new Rewriter(source.Parameters[1], arg2).Visit(source.Body);
return Expression.Lambda<Func<T1, TResult>>(newBody, source.Parameters[0]);
}
public static void Main(string[] args)
{
Expression<Func<string, string, int>> f = (a, b) => a.Length + b.Length;
Console.WriteLine(f); // (a, b) => (a.Length + b.Length)
Console.WriteLine(Bind2nd(f, "1")); // a => (a.Length + "1".Length)
}
#region Nested type: Rewriter
private class Rewriter : ExpressionVisitor
{
private readonly Expression candidate_;
private readonly Expression replacement_;
public Rewriter(Expression candidate, Expression replacement)
{
candidate_ = candidate;
replacement_ = replacement;
}
public override Expression Visit(Expression node)
{
return node == candidate_ ? replacement_ : base.Visit(node);
}
}
#endregion
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.