Dynamic Linq 的Like扩展

简介:

在上几节Linq动态组合查询时,在肖坤的Linq动态查询与模糊查询(带源码示例)时看到了微软的《Linq to SQL Dynamic 动态查询》,但是楼主说“可惜Dynamic.cs也是不能使用like的,恨啊!”。于是我下载了Dynamic .cs仔细研究了下源码,一步一步的调试,本想在微软的类库里添加如like的支持,但是调试了半天,还是无从下手。但是发现了DLinq支持对方法的调用,支持 DataContext.Orders.Where("ShipCity.Contains(@0) ","test");于是想了下我能否用正则表达式匹配Like表达式,转化为string.Contains()。就尝试Code。说句其实微软已经支持了,只是我们有一些还是习惯于Like ‘str’形式吧了。

    赶快进入主题-Code:

 

代码

 

 

         在上面代码就是正则表达式的运用,很简单。其中唯一花费了我很多时间就是我在正则表达式匹配时和修改后的string的index不一致,本想用个假单方法实现,最后还是么有办法,就只有加入了一个offset偏移量,每次删除插入的差值的和。这里就把like ‘value’ 转化为 property.Contains(value);其实和like还是有差别的Contains其实只等于 ‘%value%’。但是这里提供了一个方案,同理我们可以实现为‘%value’ 为EndWith,‘vakue%’为StartWith。由于在我们的应用中一般常用的为Contains所以暂时还么有扩展其他两个,等有时间再做(实现也简单就是判断有么有%和他的位置选择我们所转化的函数名)。

     为了在Dlinq里扩展我在where方法里面加入了传入条件字符串的转化。并加入了参数ignoreLike,默认为False。我怕的扩展有某些问题暂时还么有测试出来了,还有就是不想改变原类库。

    在我的扩展中支持ShipCity like @1 、ShipCity like 'don'、ShipCity like @0 两种形式,原来类库里面只支持第三种形式。我的前两者形式都是当做字符串处理的,因为我们的like操作一般都是对字符串操作,如果要支持其他类型可以转化类型,我以前写了一个类型属性转化的类,可以实现,但是我想这个问题么有必要。

在类库里面该的方法有(已经注释了,还是贴出来看看调用):

 

代码

 

 

   只是TODO处就是我改变的。下面该测试测试下(数据库Northwind的orders表)。

 

复制代码
ExpandedBlockStart.gif 代码
IQueryable < Orders >  q  =  DataContext.Orders
.Where(
" ShipCity like @1 and ShipCity like @0 or ShipCity like 'don' and ShipCity like 'don'
          and ShipCity like  ' don '   or EmployeeID1  = 1 " " test  " " test " ).OrderBy( " ShipCity " );
             // IQueryable<Orders> q = DataContext.Orders.Where("ShipCity.Contains(@0) ","test");
            Console.WriteLine(DataContext.GetCommand(q).CommandText);
     
复制代码

 

 

为了测试多个我邮箱投个懒就把ShipCity like 'don' 赋值了多次。 
输出sql为: 

复制代码
ExpandedBlockStart.gif 代码
SELECT   [ t0 ] . [ OrderID ] [ t0 ] . [ CustomerID ] [ t0 ] . [ EmployeeID ]   AS   [ EmployeeID1 ] [ t 0 ] . [ OrderDate ] [ t0 ] . [ RequiredDate ] [ t0 ] . [ ShippedDate ] [ t0 ] . [ ShipVia ] [ t0 ] . [ F reight ] [ t0 ] . [ ShipName ] [ t0 ] . [ ShipAddress ] [ t0 ] . [ ShipCity ] [ t0 ] . [ ShipRegion ]  ,  [ t0 ] . [ ShipPostalCode ] [ t0 ] . [ ShipCountry ]   FROM   [ dbo ] . [ Orders ]   AS   [ t0 ]   WHERE  (( [ t0 ] . [ ShipCity ]   LIKE   @p0 AND  ( [ t0 ] . [ ShipCity ]   LIKE   @p1 ))  OR  (( [ t0 ] . [ Shi pCity ]   LIKE   @p2 AND  ( [ t0 ] . [ ShipCity ]   LIKE   @p3 AND  ( [ t0 ] . [ ShipCity ]   LIKE   @p4 ))  OR  ( [ t0 ] . [ EmployeeID ]   =   @p5 ORDER   BY   [ t0 ] . [ ShipCity ]
复制代码

 

 

如果在类库中有和你的字符串等冲突就可以用ignoreLike为真,避免我的扩展。

最后希望大家一起帮我测试下,如果有什么问题请留言和Email:破狼Email指出,我好改变。

附带:扩展后的Dynamic.cs下载



本文转自破狼博客园博客,原文链接:http://www.cnblogs.com/whitewolf/archive/2010/08/03/1790954.html,如需转载请自行联系原作者
目录
相关文章
|
SQL .NET
一起谈.NET技术,NHibernate3.0剖析:Query篇之NHibernate.Linq自定义扩展
  系列引入   NHibernate3.0剖析系列分别从Configuration篇、Mapping篇、Query篇、Session策略篇、应用篇等方面全面揭示NHibernate3.0新特性和应用及其各种应用程序的集成,基于NHibernte3.0版本。
1086 0
|
SQL .NET C#
一起谈.NET技术,Linq to SQL T4 代码生成器 (二)访问设计器中的 Table 对象
  在上一篇文章中,介绍了如何访问 DataContext 对象,下面接着来讲解一下如何访问设计器中的表对象,并生成生体类代码。从 Northwind 数据库中拖一个表到设计器中。拖出来后,记得保存 dbml 文件,否则是无法访问到这个表的。
1012 0
|
SQL 存储 .NET
一起谈.NET技术,使用LINQ Expression构建Query Object
  这个问题来源于Apworks应用开发框架的设计。由于命令与查询职责的分离,使得基于CQRS体系结构风格的应用系统的外部存储系统的结构变得简单起来:在“命令”部分,简单地说,只需要 Event Store和Snapshot Store来保存Domain Model;而“查询”部分,则又是基于事件派送与侦听的系统集成。
949 0