LINQ 表达式(Expression)

可以将lambda表达式分配给Func或Action类型委托,以处理内存中的集合。.NET编译器在编译时将分配给Func或Action类型委托的lambda表达式转换为可执行代码。

LINQ引入了一种名为Expression的新类型,该类型代表强类型的lambda表达式。这意味着lambda表达式也可以分配给Expression <TDelegate>类型。.NET编译器将分配给Expression <TDelegate>的lambda表达式转换为Expression树,而不是可执行代码。远程LINQ查询提供程序使用此表达式树作为数据结构,以其构建运行时查询(例如LINQ-to-SQL,EntityFramework或实现IQueryable <T>接口的任何其他LINQ查询提供程序)。

下图说明了将lambda表达式分配给Func或Action委托与LINQ中的Expression时的区别。

ExpressionTree流程
Expression 和 Func

在下一节中,我们将学习表达式树,但首先,让我们看看如何定义和调用表达式。

定义 Expression

引用System.Linq.Expressions命名空间,并使用Expression <TDelegate>类定义一个Expression。Expression <TDelegate>需要委托类型Func或Action。

例如,你可以将 lambda 表达式赋给 Func 类型委托 的 isTeenAger 变量,如下所示:

public class Student 
{
    public int StudentID { get; set; }
    public string StudentName { get; set; }
    public int Age { get; set; }
}

Func<Student, bool> isTeenAger = s => s.Age > 12 && s.Age < 20;
示例:在VB.Net中为表达式定义Func委托
Dim isTeenAger As Func(Of Student, Boolean) = Function(s) s.Age > 12 And s.Age < 20

现在,您可以使用Expresson包装Func委托,将上述Func类型委托转换为Expression,如下所示:

 示例:在C#中定义表达式 Expresson

Expression<Func<Student, bool>> isTeenAgerExpr = s => s.Age > 12 && s.Age < 20;

示例:在VB.Net中定义表达式

Dim isTeenAgerExpr As Expression(Func(Of Student, Boolean)) = 
                                        Function(s) s.Age > 12 And s.Age < 20

以相同的方式,如果您不从委托返回值,则还可以用Expression包装Action <t>类型委托。

示例:在C#中定义表达式

Expression<Action<Student>> printStudentName = s => Console.WriteLine(s.StudentName);

示例:在VB.Net中定义表达式

Dim printStudentName As Expression(Action(Of Student) = 
                                        Function(s) Console.WriteLine(s.StudentName);

因此,您可以定义Expression <TDelegate>类型。现在,让我们看看如何调用由Expression <TDelegate>包装的委托。

调用表达式(Expression)

您可以用与委托相同的方式调用由Expression包裹的委托,但是首先需要使用Compile()方法进行编译。Compile()返回FuncAction类型的委托,以便您可以像委托一样调用它。

    示例:在C#中调用表达式

Expression<Func<Student, bool>> isTeenAgerExpr = s => s.Age > 12 && s.Age < 20;

//使用Compile方法编译Expression以将其作为委托调用
Func<Student, bool>  isTeenAger = isTeenAgerExpr.Compile();
            
//Invoke
bool result = isTeenAger(new Student(){ StudentID = 1, StudentName = "Steve", Age = 20});
Dim isTeenAgerExpr As Expression(Of Func(Of Student, Boolean)) = 
                                                    Function(s) s.Age > 12 And s.Age < 20

'使用compile方法将其作为委托调用的compile表达式
Dim isTeenAger As Func(Of Student, Boolean) = isTeenAgerExpr.Compile()

Dim result = isTeenAger(New Student() With { .StudentID = 1, .StudentName = "Steve", .Age = 20})

在下一节中将详细了解表达式树。