Linq 表达式树笔记
时间:2011-03-26 来源:小海豹
表达式树:它是语言之间的一种转换。表达式树不是可执行代码,它是一种数据结构。把代码转换成表达式树,再把表达式树转换成sql数据。
当要把c#语句转换成sql语句时,要通过表达式树expression<func<>>转换,当只操作c#语句时则直接用func<>语句即可。IQueryable<T>是一个sql集合,IEnumerable<T>是一个c#集合。他们之间需要转换。
Func是委托类型。
Func<int, int, int> function = (a,b) => a + b;
这个语句包含三个部分:
一个声明: Func<int, int, int> function
一个等号: =
一个lambda表达式: (a,b) => a + b;
变量function指向两个数字相加的原生可执行代码。上面三步的lambda表达式表示一个简短的如下的手写方法:
public int function(int a, int b)
{
return a + b;
}
上面的方法或lambda表达式都可以这样调用:
int c = function(3, 5);
当方法调用后,变量c将被设成3+5,即8。
上面声明中第一步委托类型Func是在System命名空间中为我们定义好的:
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
Expression<TDelegate>类有四个属性:
Body: 得到表达式的主体。
Parameters: 得到lambda表达式的参数.
NodeType: 获取树的节点的ExpressionType。共45种不同值,包含所有表达式节点各种可能的类型,例如返回常量,例如返回参数,例如取两个值的小值(<),例如取两个值的大值(>),例如将值相加(+),等等。
Type: 获取表达式的一个静态类型。在这个例子里,表达式的类型是Func<int, int, int>。
Compile():将数据转换回代码
如果我们可以将代码转换到数据,那么我们也应该能将数据转换回代码。这里是让编译器将表达式树转换到可执行代码的简单代码
表达式树被创建是为了制造一个像将查询表达式转换成字符串以传递给其他程序并在那里执行这样的转换任务。
:把代码,转换成数据,然后分析数据发现其组成部分,最后转换成可以传递到其他程序的字符串。
如果代码可以在程序里执行那么可以使用名为IEnumerable<T>的简单类型完成任务
如果你需要将查询表达式转换成将传递到其他程序的字符串,那么应该使用IQueryable<T>和表达式树。
IEnumerable<T>和IQueryable<T>都有方法getenumerable()方法,是对集合的操作,但是IEnumerable<T>没有表达式树,而IQueryable<T>有表达式树,表达式树是把代码转换成sql语句的,因此C#中的代码不需要转换语言,也就不需要用到表达式树,所以不用IQueryable<T>接口。
1.var为关键字,可以根据后面的初始化语句自动推断类型,这个类型为强类型。
2.初始化语句必须为表达式,不可以为空。且编译时可以推断类型。一旦初始化之后,只可以存储这种类型。
3.var声明的仅限于局部变量,不可用于字段。亦可以用于for,foreach,using 等语句中。
4.数组也可以作为隐含类型。
5.初始化语句不能是一个自身的对象或者集合初始化器,但是他可以是包含一个对象或者初始化器的一个new表达式。
6.如果局部变量声明包含了多个声明符,其类型必须相同。
7.可以使用new关键字调用匿名初始化器创建一个匿名类型的对象。
8.匿名类型直接继承自System. Object。
9.匿名类型的成员是编译器根据初始化器推断而来的一些读写属性。
7:区分IEnumerable<T>和IQueryable<T>
本地数据源用IEnumerable<T>,远程数据源用IQueryable<T>。
针对LinqLINQ TO to OBJECTS,使用Enumerable中的扩展方法对本地集合进行排序、查询等操作,查询参数接受的是Func< >。Func< >叫做谓语表达式,相当于一个委托。针对LinqLINQ TO to SQL则使用Querable中的扩展方法,它接受的参数是Expression< >。Expression< >用于包装Func< >。LinqLINQ TO to SQL引擎最终会将表达式树转化成为相应的SQL语句,然后在数据库中执行。