• LINQ模糊查询补遗之LIKE及NEWID()最终解决方案【转】


    大家刚接触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

  • 相关阅读:
    CQD(陈丹琦)分治 & 整体二分——专题小结
    [联赛可能考到]图论相关算法——COGS——联赛试题预测
    C++ 线段树—模板&总结
    树形动态规划(树状DP)小结
    树形动态规划(树形DP)入门问题—初探 & 训练
    哈希表(散列表),Hash表漫谈
    随机系列生成算法(随机数生成)
    什么是动态规划算法,常见的动态规划问题分析与求解
    数学之美系列二十四 -- 谈谈动态规划与如何设计动态规划算法
    owasp zap 安全审计工具 功能详解
  • 原文地址:https://www.cnblogs.com/cxd4321/p/1575890.html
Copyright © 2020-2023  润新知