手工把LINQ转成表达式(一) 基础知识

17 篇文章 0 订阅
10 篇文章 0 订阅
本文探讨了LINQ的强大之处,尤其是其一致的查询语法,使得无论查询什么对象,只要有适当的提供者,都能进行查询。重点在于研究如何将LINQ语句转化为Expression,包括使用词法分析器解析LINQ,解析表达式,并将LINQ关键字转换为表达式形式。作者提到,有了这样的解析器,可以实现动态运行LINQ,合并或替换LINQ,甚至构建类似SQL客户端的工具。文中提供了完整的代码供读者参考。
摘要由CSDN通过智能技术生成

LINQ其实并非是全新的概念,在编程语言中内嵌SQL或脚本进行强类型绑定查询很早就存在,LINQ之所以能让人觉得非常强大的地方在于它的设计框架可以让它不仅仅用在数据库查询方面,只要查询对象有IQueryableProvider你就可以通过LINQ去查找。

比如假设有个google的IQueryableProvider,那你只要

from page in Google
where page.Content.Contains("hello world") || page.Keyword == "hello world"
select page;

就能找到关键字包含"hello world"的所有网页,还能进一步做join, group这种操作细化查询结果。

它强大的优势就在于查询语法一致性,不管是何种东西,只要有provider就能用相同的查询语法进行查询,大大简化了查询编程的难度。

而我们这里要研究的不是如何定制一个provider,而是如何把这种查询语法转换成相应的表达式。通过观测IQueryableProvider我们发现

    public interface IQueryProvider
    {
        // Summary:
        //     Constructs an System.Linq.IQueryable object that can evaluate the query represented
        //     by a specified expression tree.
        //
        // Parameters:
        //   expression:
        //     An expression tree that represents a LINQ query.
        //
        // Returns:
        //     An System.Linq.IQueryable that can evaluate the query represented by the
        //     specified expression tree.
        IQueryable CreateQuery(Expression expression);
        //
        // Summary:
        //     Constructs an System.Linq.IQueryable<T> object that can evaluate the query
        //     represented by a specified expression tree.
        //
        // Parameters:
        //   expression:
        //     An expression tree that represents a LINQ query.
        //
        // Type parameters:
        //   TElement:
        //     The type of the elements of the System.Linq.IQueryable<T> that is returned.
        //
        // Returns:
        //     An System.Linq.IQueryable<T> that can evaluate the query represented by the
        //     specified expression tree.
        IQueryable<TElement> CreateQuery<TElement>(Expression expression);
        //
        // Summary:
        //     Executes the query represented by a specified expression tree.
        //
        // Parameters:
        //   expression:
        //     An expression tree that represents a LINQ query.
        //
        // Returns:
        //     The value that results from executing the specified query.
        object Execute(Expression expression);
        //
        // Summary:
        //     Executes the strongly-typed query represented by a specified expression tree.
        //
        // Parameters:
        //   expression:
        //     An expression tree that represents a LINQ query.
        //
        // Type parameters:
        //   TResult:
        //     The type of the value that results from executing the query.
        //
        // Returns:
        //     The value that results from executing the specified query.
        TResult Execute<TResult>(Expression expression);
    }

它的2个主要方法CreateQuery和Execute参数都是表达式,而根据提示这个表达式就是代表了LINQ语句,那LINQ语句怎么会变成Expression的呢?这里就是要研究这个。

把LINQ转换成表达式有许多工作要做,首先是我们要有一个能解析LINQ的词法分析器,这里就用之前介绍过的lambda表达式解析http://blog.csdn.net/guoyichao/article/details/6637195中修改过的Irony grammar进行LINQ解析;然后是LINQ里会包含大量的表达式也需要解析,正好我们之前已经做完了这部分工作直接用之前的成果就行;最后则是把LINQ关键字转换成相应表达式,这是重点工作后续会一一说明。

当我们有了这个解析器后可以做些什么?我们可以动态运行LINQ!还记得微软C# sample里提供的dynamic query例子么?这个解析器比它更进一步。我们可以用它来合并多个LINQ,也可以用一个LINQ替换掉另一个LINQ的某一部分,我们甚至可以做一个工具让用户直接输入LINQ进行查询就像一些SQL客户端一样方便(当然不用这个解析器你也可以用CodeDOM来实现该相同功能)。

在实现LINQ解析过程中,由于采用了手工硬编码方式来实现表达式转换,所以代码完全是以一种逐句翻译过程写的,整体结构不美观,在这里先给出完整代码,想要直接看代码的可以去http://code.google.com/p/tinynetevent/downloads/list下载ExpressionParser0809.zip。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值