表达式目录树——自定义LINQ Provider实现LINQ to LDAP查询(其二)
2013-01-27 01:49
465 查看
引言
说明
由于博客园是个技术社区,所以我得显得严谨点,这里留下几点说明,我会在接下来的几篇文章中(如果有的话)重复这个说明。其一,这篇(或者系列,如果有的话)文章是为了和大家一起入门(注意不是指导)。所以所编写的代码仅仅是示例的,或者说是处于编写中(完善中)的。
其二,至于为什么在学习的过程中就着手写这些文章,那是因为我深深觉得作为入门,这些内容还是容易的,但是常常让人却而退步。比如在一周之前,我还问博客园中的另一位博主,请求资料。那个时候我还觉得非常困难,非常苦恼。但是,经过一些摸索,一些文章的指导之后,却轻轻叩开了LINQ的门,一窥其瑰丽了。
其三,其实网上并不是没有LINQ的教程(指编写Provider)。但是“会”和不会往往隔了一点顿悟。就像“水门事件”一样。所以作为初学者来和大家一起探讨可以让彼此更同步。
其四,这真的是一个非常有挑战,非常有趣的内容。我接触了之后就忍不住和大家一起分享,邀大家一起参与冒险。
最后,这里列出所有我参考的,觉得有价值的资源。
其一,MSDN的博客: http://blogs.msdn.com/b/mattwar/archive/2007/07/30/linq-building-an-iqueryable-provider-part-i.aspx
这系列文章直接和本系列文章相关。07年的帖子,13年才发现,真该面壁思过。
其二,http://weblogs.asp.net/mehfuzh/archive/2007/10/04/writing-custom-linq-provider.aspx
待会会在文章中引用到这个博主写的一个非常短小的Provider示例。
其三,博客园中某个博主的作品http://www.cnblogs.com/Terrylee/category/48778.html
大神的文章读起来有点累,所以这系列我访问了好几次,愣是没看懂怎么回事,不过里面有张图挺不错。
接上文
在上文中,我们从接口着手,为了构造自己的LINQ Provider而努力。我们把要实现两个接口减少为只要实现一个接口。通过对剩下的一个接口中要实现的一组方法提供固定实现,现在我们仅需要实现一组方法就能完成工作了。但是,这正是最具挑战的部分。我们将在这个方法中完成“转换”,“查询”,“转化”三个步骤。其中,如何将LINQ查询通过合适的逻辑转换为一种目标查询语句是最核心的部分。此外,为了进行优化,我们还需要处理缓存等一系列操作。是不是很复杂?我承认,如果一开始就考虑全部事项,对于我们这种初学者而言简直就是灾难。但是不要忘了,我们的目的是尽快的构造自己的Hello World,以让自己充满信心。就像编写第一个App的时候,没有考虑一开始就考虑using(或者include)是什么,System.Console(或者printf)是什么,为什么要用大括号,以及为什么要使用引号(同样的,上篇文章中所采取的一些操作,都没有进行仔细的梳理,姑且就像使用VS设计WinForm的时候生成的designer文件一样,认同它)。Just do it,我们先搞定一种情形,然后再搞定第二种,第三种...Just do it
目标
在SQL查询中,使用的最频繁的可能就是Where筛选了,LDAP查询也一样。所以我们就从Where开始。Where是扩展方法,从根本上讲,它有两个参数,第一个表示调用者(this),第二个接受一个谓词,姑且认为是一个返回值为bool的委托好了。再简单一点,我们认为这个委托的主题部分是string类型的Contains方法。嗯,其实就是“选取xx部分包含关键字xxx的用户”这样的筛选表达式。使用一个常见的表达式的话,就是形如:context.User.Where(u => u.Name.Contains("sample"))或者from u in context.User where u.Name.Contains("sample")【记为表达式A】的LINQ查询。然后如果是直接使用LDAP查询呢?Filter字符串就应该是(假定我们检索UPN)(&(objectClass=User)(userPrincipalName=*sample*))【记为表达式B,虽然他只是字符串】。也就是说我们要把A转换为B。表达式目录树
/article/4583678.html这篇文章初步说明了表达式目录树是啥。但是和我们现在要做的事情还不够接近。所以我现在定义了一个User类型,然后在VS中写了一个表达式来一窥究竟。
View Code
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace Sample { class Program { static void Main(string[] args) { bool value1 = true && false || true && false || false; /*如果&&的优先级比||高或者相反,则右结合和左结合都无所谓*/ bool value2 = true && false || true && false || false && true || true; Console.WriteLine(value1); Console.WriteLine(value2); Console.ReadKey(); /*结果是 * false true*/ } } }
由上面的例子可以看出,&&的优先级高于||的优先级。后来又查阅了C#高级编程,P169。这里贴上一个表格来。如此一来,结合性就不那么重要了。
结语
看到这个标题就意味着这一篇也结束了。我个人性子比较急,想到什么就像写出来,所以会导致内容质量很差,还希望大家别见怪。其实这篇本来可以作为完结篇的,因为接下来的事情无非是查询,转换。不过我又想到了一些东西,所以想在最后的时候作为补充。LINQ之路漫长,不过我会坚持下去的。:)相关文章推荐
- 从接口说起——自定义LINQ Provider实现LINQ to LDAP查询(其一)
- Hello My LINQ World——自定义LINQ Provider实现LINQ to LDAP查询(其三)
- Linq to sql 实现多条件的动态查询(方法一)
- LINQ to DataSet实现复杂数据查询
- LINQ : 如何为LINQ TO SQL实现自定义业务逻辑
- 转载:LINQ to DataSet实现复杂数据查询
- LINQ to DataSet实现复杂数据查询
- Linq to SQL实现链接加条件查询
- Linq Provider for MySql, Oracle and PostgreSQL Linq to Oracle 使用教程目录
- Linq与where实现查询(Linq to Entity)【IEnumerable与IEnumerator与IList】|自己实现foreach的功能
- 关于Linq to sql 实现 模糊查询 string数组
- 学习并使用了两种linq to entity 的实现sql关键字in的查询方法
- LINQ : 如何为LINQ TO SQL实现自定义业务逻辑
- Lambda表达式--使用方法语法的复杂查询: join (在单个 LINQ to Entities 查询中的两个结构上不兼容的初始化过程中出现类型)
- LINQ to SQL 第九节 在控件中使用自定义的LINQ表达式(翻译自scott的博客)
- Linq to Sql:N层应用中的查询(上) : 返回自定义实体
- atitit. 集合groupby 的实现(2)---自定义linq查询--java .net php
- LINQ to Entities,基于方法查询,查询表达式语法
- LINQ to DataSet实现复杂数据查询(转)
- Linq to Sql:N层应用中的查询(上) : 返回自定义实体