日期:2014-05-20  浏览次数:21115 次

ExpressionVisitor到底干嘛用的?msdn没怎么看懂
最近实现IQueryProvider接口,用.net reflector把工作原理大概看懂了点,但涉及到分析lambda表达式的那部分就发晕了,网上说要用ExpressionVisitor,但我看了一些示例,发现这个东西把一些数据拆开了又给封装回去了,而且几乎没作任何改变,我需要的是能把lambda表达式分析成sql语句,或者说分析一部分也行,之前分析过一个,但那个写得乱了,想重新写

------解决方案--------------------
ExpressionVisitor

=========
了解一下计算机语言文化和命名习惯,你就知道这是按访问者模式写滴东西

至于你说的分拆又装回去了,自然就如此了,访问者模式原本就要求对象是对象,算法是算法。你分拆的部分都是“token”对象,而这些“token”的算法解析都封在接口内部

ps:其实做表达式分析这样的工作,正常顺序先写出正常sql(如果要的sql),使用一些词法分析工具(如irony)分拆出正常的条达树,然后在按表达式的指示利用访问者模式把对象组合起来“拼凑”成正常表达式

比如你想扩展一个 in() 查询,那么首先就的写一个正常sql in语句出来,然后用词法工具解出语法树,观察in这个token应该出现在语法树的那个部位,接着写一个token扩展,利用ExpressionVisitor把原始的语法树拆开,再把你写的那个token挂接到他应该挂接的部位,然后重新送回去。

表达式树是延后解析,所以当系统按照语法树解析的时候,会解析出你挂接的那个token,并会访问你挂接的和你这个token相对应的算法,自然你就把你的in解析给混进去了
------解决方案--------------------
token是编译原理之词法分析里的一个专用词,就相当与名词解析

这些token就是在ExpressionVisitor里看到的那些case "and",case "OR", case "Where",这些就是微软内置的语法token,当然对于sql解析来说这是不够滴,起码最明显 in,like 不在其中。这也是你和博客园那些人原意自己在扩展的原因

这样把,你自己去博客园下一个custom linq provide的例子(博客园有很多这种例子,这是那边的那些人兴趣所在),看看就明白了 
------解决方案--------------------
你为什么看不懂?也许你想从设计模式找答案,但是越看越糊涂。事实上,如果你把Expression看成一个抽象语法树的话,那么LINQ Provider其实就是在做编译原理的后半段,将语法树转换为目标代码。(前半段是把源代码通过词法分析、语法分析转换成抽象语法树,也叫中间代码)。