zoukankan      html  css  js  c++  java
  • LINQ如何实现模糊查询

    大家刚接触LINQ的时候或许都会和我一样,整的一句话:那是相当滴激动!

    左一句lambada右一句lambada,那简直是程序员的艺术。

    写着写着,我靠,问题来了,LINQ TO SQL中的like怎么实现?

    有人说:我用SqlMethods,例:

    var query = from c in LQDC.Customers

          where SqlMethods.Like(c.City, "L_n%")

    select c;

    可是问题依旧,假如我用的是通用字段模糊查询呢?例如我一个下拉列表里有所有的字段名,那么客户选择下拉列表是随机的,那我不是要

    switch(item){

    case "city":

    ...

    break;

    case "name":

    ...

    break;

    }

    有几个字段就写几个case,我靠,疯了。

    又有人说了,那用反射。。我靠,人家用LINQ的目的是什么,提高开发效率,减少开发时间,而且LINQ的反射也不是一般人随便就写得出来的。

    哎,没办法,查了很多资料,解决方法如下:

    (1)通过直接执行查询语句,这也是LINQ的老爸估计想到目前LINQ不完善而专门留下来的绝招:

    LinQDataContext LQDC = new LinQDataContext();

    LQDC.ExecuteQuery("select * from table where item like %ak47%");

    这里顺带提醒大家%ak47%是会丢失数据库索引的,而ak47%则不会,要怎么解决想想博客,这里就不扯那么远啦。

    有人讲啦,我靠又回到土办法啦,我讲:你NND,谁叫它不完善呢?

    (2)调用存储过程。

    写好一个存储过程,例如名称叫p_LikeSelect;

    ALTER PROCEDURE [dbo].[p_LikeSelect]   @tablename nvarchar(255),   @columnname nvarchar(255),

    @value nvarchar(255) AS BEGIN     set nocount on;     declare @sqlcommand nvarchar(max);     set @sqlcommand = 'select * from '+@tablename+' where.....(后面自己写啦)

    exec sp_executesql @sqlcommand ; END

    但是问题又来啦,当你把这个存储过程通过服务器资源管理器拖进dbml窗口以后,看看里面的返回值,我靠,不管你是左拖还是右拖上拖下拖,反正拖死你还是返回int,NND,你不能智能点吗?造成的原因是存储过程结尾用了exec,但是你要实现动态拼接字符串必须用exec,懂的朋友都知道(所以如果你结尾是select...什么的,它才可以识别出一个ISingleResult<T>或IMultipleResults<T>的返回类型,然后通过属性修改器把它返回值手动修改成IQueryable<Customers>这样才能最终被使用和保存)。

    没办法,那只好手动强行修改dbml下的linq.designer.cs文件,打开找到

      [Function(Name="dbo.p_LikeSelect")]   public int p_TYSelect([Parameter(DbType="NVarChar(255)")] string tablename, [Parameter(DbType="NVarChar(255)")] string @columnname.......)   {    IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), tablename, diskname);    return ((int)(result.ReturnValue));   }

    把里面所有类型int全部修改成IQueryable<Customers>如下:

      [Function(Name="dbo.p_LikeSelect")]   public IQueryable<Customers> p_TYSelect([Parameter(DbType="NVarChar(255)")] string tablename, [Parameter(DbType="NVarChar(255)")] string @columnname.......)   {    IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), tablename, diskname);    return ((IQueryable<Customers>)(result.ReturnValue));   }

    呕,擦了一把汗,可是,神种是喜欢作弄人,当你再次修改dbml文件的时候,所有代码又被重新覆盖了,所以目前我最讨厌LINQ的另外一个原因就在此了。真想骂它!这就意味着只要你系统没有完成你就别想该dbml文件。。。费。

    (3)我发怒了,要使用暴力了!!

    从网上下载了DynamicLibrary.cs或叫Dynamic.cs的,大小越70-80KB左右,

    using System.Linq.Dynamic; //using一下。

    ok,开始有搞头啦。举个例子,所有字段item和查询的值value都可以动态啦,下面我截取了一段我项目中的使用(写得不好不要打我呀)

                if (selectnum == 0) {                 IQ = LQDC.Transport_Inner;             } else {                 switch (type) {                     case "精确":                         if (itemtype == "tree" || itemtype == "specialtext") {                             IQ = LQDC.Transport_Inner.Where(item + "=@0", value);                         } else if (itemtype == "bit") {                             IQ = LQDC.Transport_Inner.Where(item + "=@0", Convert.ToBoolean(value));                         } else if (itemtype == "text") {                             if (!value.Trim().Equals("")) {                                 IQ = LQDC.Transport_Inner.Where(item + "=@0", double.Parse(value));                             } else {                                 IQ = LQDC.Transport_Inner.Where(item + "=null");                             }                         } else {                             IQ = LQDC.Transport_Inner.Where(item + ">=@0 and " + item + "<@1", date1.Date, date2.Date);                         }                         break;                     case "模糊":                         StringBuilder sb = new StringBuilder();                         IQ = LQDC.Transport_Inner.Where(@"BackNum.Contains(""000147"")");                         break;                 }             }

    动态的内容都在“精确”里面的Where里,大家应该很容易看懂(还包括动态时间的比较)

    精华在最后“模糊”那,你可以通过查询LINQ生成的SQL语句得到:

    SELECT * FROM [dbo].[Transport_Inner] AS [t0]

    WHERE [t0].[BackNum] LIKE @p0

    类似于匹配以000147开头的或是中间的或是结尾的,类似%000147%嘿嘿。

    我靠,太牛了。真的感动了一次。神呀,你终于拯救了我!!!

    终于搞定了,呼呼,,,用了两年LINQ一直捆绕着我的LIKE终于搞死它了。

    好了,还剩下一个大问题,假如我想用到sql中的new id()这个随机查询一个记录,怎么办?LINQ中也没有呀,同样得用到Dynamic.cs。

    好了使用起来也很方便,如下,查询ID>5并小于100的随即5条记录。我靠,牛:

    var query = LQDC.Transport_Inner.Where("ID>@0 and ID<@1", 5, 100).Select("new(id)").Take(5)

    当然,这只能返回IQueryable而非IQueryable<T>

    那么关于LINQ的NEW ID()还有两个方法,这些网上资料就很多了,而且也很好用,那我就不贴出来了,大家可以自己搜。

    象我这么懒的人,居然写了这么多,实在是因为一时激动,希望对学习或使用LINQ的人有所帮助,也希望LINQ能在.NET4.0中发挥更出色的作用!!!LINQ,加油!

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/alamiye010/archive/2009/03/02/3950597.aspx

  • 相关阅读:
    UVALive 5983 MAGRID DP
    2015暑假训练(UVALive 5983
    poj 1426 Find The Multiple (BFS)
    poj 3126 Prime Path (BFS)
    poj 2251 Dungeon Master 3维bfs(水水)
    poj 3278 catch that cow BFS(基础水)
    poj3083 Children of the Candy Corn BFS&&DFS
    BZOJ1878: [SDOI2009]HH的项链 (离线查询+树状数组)
    洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
    洛谷P3065 [USACO12DEC]第一!First!(Trie树+拓扑排序)
  • 原文地址:https://www.cnblogs.com/zgblog/p/2498056.html
Copyright © 2011-2022 走看看