我先抛出一些问题
要从sqlserver数据库某张表中查找某个叫 zhangsan的人的信息怎么找?很简单 sql语句: select * from _yourTable where name='zhangsan'现在同样的数据存放在xml文件里,我也要找到叫张三的怎么办?(不使用linq to xml)也不复杂,使用xml 的XPath也可以找出来。现在这些数据存放在其他类型的数据库中咋办? o(╯□╰)o 继续写可能不一样的sql语句.....................这样子针对同样的数据存放在不同介质中(内存,xml, 远程数据库 )有没有可能设计一种 数据结构能简明的表达这种意思,然后针对不同的存储介质在解析成对应的处理方式呢?只要能解析成下面这样子的二叉树数据结构就可以了。
要表达这样的意思,就要用到今天的主角了 lambda 表达式树。lambda 如果用作委托的参数,那他就会在底层被编译为一个匿名函数,而如果传给C# ExPRession那就成了一个表达式树了,相当于是存储的描述数据结构的信息,这个信息可以被分析然后处理。如下Expression<Func<string,bool>> filter=name=>name=="zhangsan";现在 filter和委托对象就不一样了,它并不是可执行代码,如果直接filter()编译会出错,如果现在又要想从个表达式树信息变成可执行代码怎么办?如下 Expression< Func<string , bool >> filter = x => x == "zhangsan" ; var compile = filter.Compile(); bool iszhangsan = compile("zhangsan" ); Console.WriteLine(iszhangsan); Console.ReadKey();
也可以对树的结构进行解析,Expression<Func <string, bool>> filter = x => x == "zhangsan" ; //我们可以对这个表达式树进行解析 //从名称也可以看出来二叉树 BinaryExpression body = (BinaryExpression)filter.Body; ParameterExpression left = (ParameterExpression)body.Left; ConstantExpression right = (ConstantExpression)body.Right; string type = body.NodeType.ToString(); Console.WriteLine("树的左边是{0},节点符号{1},树的右边{2}" ,left,type,right);
可以看到存在一个表达式树,这个表达式树就存储了上面的linq 语句想要表达的行为信息,而provider则可以显示出接下来就翻译这个行为信息成为新的可执行代码的程序,如linq to sqlserverprovider (自带) linq to Oracle等。而之所以要进行这样由C#代码翻译成表达式树数据信息在翻译成可执行代码的原意在于。你最终是要生成sql语句串通过网络发送到远程数据库在查询出结果才可以嘛。
当然如何从上面的代码得出表达式树,又怎么分析得出合适的sql语句就不在讨论范围之内了,这里面有比较复杂的算法。对于linq to objects 返回的则是IEnumerable 里面就不需要什么表达式树来存储信息了,因为本身就是针对处于同一块内存中的数据进行查询,直接逻辑查找就可以了。
新闻热点
疑难解答