我有以下形式的表达式:
Expression<Func<T, bool>> predicate = t => t.Value == "SomeValue";
是否可以创建此表达式的“部分应用”版本:
Expression<Func<bool>> predicate = () => t.Value == "SomeValue";
NB 这个表达式实际上从未被编译或调用,它只是被检查以生成一些 SQL。
我有以下形式的表达式:
Expression<Func<T, bool>> predicate = t => t.Value == "SomeValue";
是否可以创建此表达式的“部分应用”版本:
Expression<Func<bool>> predicate = () => t.Value == "SomeValue";
NB 这个表达式实际上从未被编译或调用,它只是被检查以生成一些 SQL。
这可以通过编写自定义 ExpressionVisitor 并将参数替换为您在闭包中捕获的常量表达式来轻松实现:
public class Foo
{
public string Value { get; set; }
}
public class ReplaceVisitor<T> : ExpressionVisitor
{
private readonly T _instance;
public ReplaceVisitor(T instance)
{
_instance = instance;
}
protected override Expression VisitParameter(ParameterExpression node)
{
return Expression.Constant(_instance);
}
}
class Program
{
static void Main()
{
Expression<Func<Foo, bool>> predicate = t => t.Value == "SomeValue";
var foo = new Foo { Value = "SomeValue" };
Expression<Func<bool>> result = Convert(predicate, foo);
Console.WriteLine(result.Compile()());
}
static Expression<Func<bool>> Convert<T>(Expression<Func<T, bool>> expression, T instance)
{
return Expression.Lambda<Func<bool>>(
new ReplaceVisitor<T>(instance).Visit(expression.Body)
);
}
}
我认为这应该有效:
Expression predicate2 = Expression.Invoke(predicate, Expression.Constant(new T() { Value = "SomeValue"}));
Expression<Func<bool>> predicate3 = Expression.Lambda<Func<bool>>(predicate2);
不知道这是否易于解析以生成 SQL(它在编译时工作 - 我试过)。