我想要编写两个Linq表达式的结果。它们以
的形式存在Expression<Func<T, bool>>
所以我要编写的两个本质上是一个参数(类型为T)的委托,它们都返回一个布尔值。我想要的结果是对布尔值的逻辑评价。我可能会将它作为扩展方法实现,所以我的语法类似于:
Expression<Func<User, bool>> expression1 = t => t.Name == "steve";
Expression<Func<User, bool>> expression2 = t => t.Age == 28;
Expression<Func<User, bool>> composedExpression = expression1.And(expression2);
稍后在我的代码中我想评估组合表达式
var user = new User();
bool evaluated = composedExpression.Compile().Invoke(user);
我已经探讨了一些不同的想法,但我担心它比我希望的更复杂。这是怎么做到的?
答案 0 :(得分:16)
以下是一个例子:
var user1 = new User {Name = "steve", Age = 28};
var user2 = new User {Name = "foobar", Age = 28};
Expression<Func<User, bool>> expression1 = t => t.Name == "steve";
Expression<Func<User, bool>> expression2 = t => t.Age == 28;
var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());
var result = Expression.Lambda<Func<User, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);
Console.WriteLine(result.Compile().Invoke(user1)); // true
Console.WriteLine(result.Compile().Invoke(user2)); // false
您可以通过扩展方法重用此代码:
class User
{
public string Name { get; set; }
public int Age { get; set; }
}
public static class PredicateExtensions
{
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1,Expression<Func<T, bool>> expression2)
{
InvocationExpression invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);
}
}
class Program
{
static void Main(string[] args)
{
var user1 = new User {Name = "steve", Age = 28};
var user2 = new User {Name = "foobar", Age = 28};
Expression<Func<User, bool>> expression1 = t => t.Name == "steve";
Expression<Func<User, bool>> expression2 = t => t.Age == 28;
var result = expression1.And(expression2);
Console.WriteLine(result.Compile().Invoke(user1));
Console.WriteLine(result.Compile().Invoke(user2));
}
}
答案 1 :(得分:5)
您也可以使用LinqKit,它可以为您完成所有这些工作。请查看此链接 http://www.albahari.com/nutshell/linqkit.aspx