• 突发奇想-关于列表页面查询条件自动组装的实现


    此方法不仅使用于ASP.NET WEB FORM ,而且适用于ASP.NET MVC。

    当列表页面需要大量的查询条件,你该怎么办?

    你是否厌倦了一个个查询条件的拼接?

    你是否在想能不能有一种工具让这些查询条件自动组装?

    今天,联想到ASP.NET MVC的模型绑定以及前台验证的实现思想,突发奇想,想要开发一个能够自动组装查询条件并且自动拼接成sql查询条件的工具。

    原始方法的实现                     

    第一步:列表页面查询表单的建立

    由于本人几乎不会拖拽服务端框架,以前在解决列表页面多条件搜索的的实现方法是,通过js将查询条件极其值通过js拼接成一个url后缀的ur,然后通过get方式提交到后台,然后再才拆卸url后缀,最后手动拼接sql语句,其过程真是十分繁琐无味。

    以前的做法前台代码如下所示:

    l

     <script type="text/javascript">
            $(function () {
                $("#search").click(function(){
    //url的拼接
                    window.location.href="<%=ListUrl%>?ddlsuggestionType="+$("#ddlsuggestionType").val()+"&key="+$("#txtkey").val()+"&txtFrom="+$("#txtFrom").val()+"&txtTo="+$("#txtTo").val();
                });
            })
          
        </script>
    </head>
    <body>
        <form id="form1" runat="server">
            <div class="alert alert-info">当前位置<b class='tip'></b><%=ListTitle %></div>
          
            <table class="tb">
               
                <tr height="45">
                    <th>意见分类:<select id="ddlsuggestionType" class="ipt width200 " runat="server"></select>
                        关键字:<input type="text" id="txtkey" runat="server" class="ipt width200 " />
                        发布人登录名:<input type="text" id="txtFrom" runat="server" class="ipt width200 " />
                        接收人登录名:<input type="text" id="txtTo" runat="server" class="ipt width200 " />
                        <input type="button" id="search" class="btn" value="搜索" />
                    </th>
                </tr>
                
                <tr height="45">
                    <th>
                        <input type="button" class="btn  btn-primary" onclick='window.location.href="<%=EditUrl %>    ";' value="添加" />
                        &nbsp;&nbsp;
                         <input type="button" class="btn" onclick='window.location.href=window.location.href;' value="刷新" />
                    </th>
                </tr>
            </table>
            <table class="tb" id="list">

    第二步:url参数的拆卸以及sql条件的拼接

    后台代码如下:

     1 //拆卸url参数
     2  private void BindData()
     3     {
     4         GetSuggestionTypeList();
     5         var suggestionType = Request.QueryString["ddlsuggestionType"];
     6         var key = Request.QueryString["key"];
     7         var txtFrom = Request.QueryString["txtFrom"];
     8         var txtTo = Request.QueryString["txtTo"];
     9         var userType = GetUser().UserType;
    10         var entitys = BLL.BLLSession.Info_SuggestionBLL.GetSearchRptEntitys(suggestionType, key, userType,GetUser().Id,txtFrom,txtTo, Pager.CurrentPageIndex, Pager.PageSize, out  RowCount, out  PageCount);
    11         BindRptData(rptList, entitys);
    12         Pager.RecordCount = RowCount;
    13         ddlsuggestionType.Value = suggestionType;
    14         txtkey.Value = key;
    15     }
    16 
    17 //sql的拼接
    18  public List<Info_Suggestion> GetSearchRptEntitys(string suggestionType,string key,int userType,int userid,string txtFrom,string txtTo,int PageIndex, int PageSize, out int RowCount, out int PageCount)
    19         {
    20             string where = " and Deleted=0";
    21             if (!string.IsNullOrEmpty(suggestionType) && suggestionType != "-1")
    22             {
    23                 where += " and SuggestionTypeId=" + suggestionType;
    24             }
    25             if (!string.IsNullOrEmpty(key))
    26             {
    27                 where += " and KeyWord like '%" + key.Replace("'", "") + "%'";
    28             }           
    29             if (userType != 1)//管理员可以查看所有的
    30             {
    31                 where += " and (FromUser=" + userid + " or ToUser=" + userid + ")";
    32             }
    33             if (!string.IsNullOrEmpty(txtFrom))
    34             {
    35                 where += " and FromUsrName='" + txtFrom.Replace("'", "") + "'";
    36             }
    37             if (!string.IsNullOrEmpty(txtTo))
    38             {
    39                 where += " and ToUserName='" + txtTo.Replace("'", "") + "'";
    40             }      
    41             List<Model.Info_Suggestion> entitys = null;
    42             entitys = GetPagedEntitys(PageIndex, PageSize, out RowCount, out PageCount, null, where, "Id desc");
    43             return entitys;
    44         }

    现在我想做的是让前台url自动组装,后台自动拆卸url参数,并且自动拼接sql语句

    列表页面查询条件自动组装的实现

    的的

    第一步:将查询条件放在请求方式为get 的form中

    代码如下:

     1  <form method="get">
     2         <table class="tb">
     3             <tr  class="treven height45">
     4                 <th class="thCss">
     5                    标题: <input name="Title_string_like" type="text" id="Title_string_like" runat="server" class="ipt width200 " />
     6                      来源: <input name="FromWhere_string_like" type="text" id="FromWhere_string_like" runat="server" class="ipt width200 " />
     7                     <input type="submit" class="btn" value="搜索" />
     8                 </th>
     9             </tr>
    10             <tr class="height45">
    11                 <th>
    12                     <input type="button" class="btn  btn-primary" onclick='window.location.href="<%=EditUrl %>    ";' value="添加" />
    13                     &nbsp;&nbsp;
    14                      <input type="button" class="btn" onclick='window.location.href=window.location.href;' value="刷新" />
    15                 </th>
    16             </tr>
    17         </table>
    18     </form>

    说明:上述代码会自动拼接url参数,也许你发现了表单的name很特别,这里使用的是约定大于配置的思想(如果你了解过mvc的话会发现其中到处都充斥着这种思想,比如mvc前台验证机制等等)。查询表单的那么格式为name_[int|string]_[like|equal],name代表对应的数据库字段名称,int和string代表的是数据类型,datetime类型默认为int类型,like代表模糊查询(暂不支持左模糊和右模糊),equal代表等值查询。我们约定以此方式为查询表单命名,方便在后台对此表单自动拆卸,组装sql条件。

    第二步:建造url参数自动拆卸组装sql条件的工具

    方法如下:

     1  public string GetQueryString(string name)
     2         {
     3            string temp= Request.QueryString[name];
     4            return string.IsNullOrEmpty(temp) ? "" : temp;
     5         }
     6         /// <summary>
     7         /// 自动组合拼接查询语句-使用约定大于配置的思想
     8         /// 查询表单的那么格式为name_[int|string]_[like|equal],name代表对应的数据库字段名称,int和string代表的是数据类型,datetime类型默认为int类型,like代表模糊查询(暂不支持左模糊和右模糊),equal代表等值查询。
     9         /// </summary>
    10         /// <returns></returns>
    11         public string GetQueryString()
    12         {
    13             string where = "";
    14             System.Collections.Specialized.NameValueCollection collection = Request.QueryString;
    15             var keys= collection.AllKeys;//key 的格式为 name_[int|string]_[like|equal]
    16             foreach (var key in keys)
    17             {
    18                 string[] split = key.ToString().Split('_');
    19                 string name = split[0];                
    20                 string type = split[1] == "int" ? "" : "'";               
    21                 string le = split[2] == "equal" ? "=" : "like";
    22                 string l = le == "like" ? "%" : "";
    23                 string value = GetQueryString(key.ToString());
    24                 if (type=="'")
    25                 {
    26                     value = value.Replace("'","");//手动过滤掉',不足之处  应该使用参数化查询
    27                 }
    28                 if (!string.IsNullOrEmpty(value))
    29                 {
    30                     string tempStr = string.Format(" and {0} {1} {2}{3}{4}{3}{2} ", name, le, type, l, value);
    31                     where += tempStr;
    32 
    33                 }                
    34             }
    35             return where;
    36             
    37         }

    说明:我们知道sql的查询条件有等值查询和模糊查询(这里暂不考虑左模糊和右模糊),sql里面的值类型大致可以分为整型和字符串类型,我们把bit类型和datetime类型看做是整型,因为它们在值的两端不会加 "'"。这样我们可以根据我们前面在查询列表页面以name_[int|string]_[like|equal]的方式命名表单。具体操作,在以上代码中可以看到,不作说明,关于数据非法性验证在这里没做说明。

    数据查询方法如下

     private void BindData()
        {
            string where=GetQueryString();
            var entitys = bll.GetPagedEntitys(Pager.CurrentPageIndex, Pager.PageSize, out RowCount, out PageCount,  where, null);
    
            BindRptData(rptList, entitys);
            Pager.RecordCount = RowCount;
        }

    有些朋友该说,现在我们都使用的是强类型ORM框架处理数据的CURD。你怎么还在这里拼接sql语句,其实在这里我的底层操作数据库的也是强类型ORM框架EF。但是我个人认为针对于多条件查询的方法,使用Lamda作为条件显的特别臃肿。而我恰恰是利用了EF支持原生态的sql查询而且可以生成强类型model的特性拼接sql。这样还有一个好处是性能会有所提高。

    但是经过使用sql server profiler跟踪发现了两个不足之处。

    1.EF自动生成的sql分页语句并不是性能最好的分页语句(其实微软这样做是有原因的)。

    2.如果直接使用EF提供的拼接sql语句结合分页查询时,跟踪发现对数据的分页是在内存中进行的(这实在太可怕了!!!)。

    以上言论纯属本人言论,如有不妥或者错误的地方欢迎指正,同时在下篇博客我将给出以上两个问题的解决方案。

  • 相关阅读:
    C#:如何设置MDI窗体
    asp.net在类库中使用EF 6.0时的相关配置
    asp.net中使用jquery ajax保存富文本的问题
    Asp.net Api中使用OAuth2.0实现“客户端验证”
    NLog在asp.net中的使用
    元素的隐藏特性
    jQuery 使用笔记
    获取标签的所有选择器存放在一个数组
    自己绘制的flex布局思维导图
    js打印三角形
  • 原文地址:https://www.cnblogs.com/eggTwo/p/3682955.html
Copyright © 2020-2023  润新知