您的位置:首页 > 其它

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

2014-04-23 15:07 555 查看
此方法不仅使用于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="添加" />
  
<input type="button" class="btn" onclick='window.location.href=window.location.href;' value="刷新" />
</th>
</tr>
</table>
<table class="tb" id="list">


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

后台代码如下:

//拆卸url参数
private void BindData()
{
GetSuggestionTypeList();
var suggestionType = Request.QueryString["ddlsuggestionType"];
var key = Request.QueryString["key"];
var txtFrom = Request.QueryString["txtFrom"];
var txtTo = Request.QueryString["txtTo"];
var userType = GetUser().UserType;
var entitys = BLL.BLLSession.Info_SuggestionBLL.GetSearchRptEntitys(suggestionType, key, userType,GetUser().Id,txtFrom,txtTo, Pager.CurrentPageIndex, Pager.PageSize, out  RowCount, out  PageCount);
BindRptData(rptList, entitys);
Pager.RecordCount = RowCount;
ddlsuggestionType.Value = suggestionType;
txtkey.Value = key;
}

//sql的拼接
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)
{
string where = " and Deleted=0";
if (!string.IsNullOrEmpty(suggestionType) && suggestionType != "-1")
{
where += " and SuggestionTypeId=" + suggestionType;
}
if (!string.IsNullOrEmpty(key))
{
where += " and KeyWord like '%" + key.Replace("'", "") + "%'";
}
if (userType != 1)//管理员可以查看所有的
{
where += " and (FromUser=" + userid + " or ToUser=" + userid + ")";
}
if (!string.IsNullOrEmpty(txtFrom))
{
where += " and FromUsrName='" + txtFrom.Replace("'", "") + "'";
}
if (!string.IsNullOrEmpty(txtTo))
{
where += " and ToUserName='" + txtTo.Replace("'", "") + "'";
}
List<Model.Info_Suggestion> entitys = null;
entitys = GetPagedEntitys(PageIndex, PageSize, out RowCount, out PageCount, null, where, "Id desc");
return entitys;
}


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

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

的的

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

代码如下:

<form method="get">
<table class="tb">
<tr  class="treven height45">
<th class="thCss">
标题: <input name="Title_string_like" type="text" id="Title_string_like" runat="server" class="ipt width200 " />
来源: <input name="FromWhere_string_like" type="text" id="FromWhere_string_like" runat="server" class="ipt width200 " />
<input type="submit" class="btn" value="搜索" />
</th>
</tr>
<tr class="height45">
<th>
<input type="button" class="btn  btn-primary" onclick='window.location.href="<%=EditUrl %>    ";' value="添加" />
  
<input type="button" class="btn" onclick='window.location.href=window.location.href;' value="刷新" />
</th>
</tr>
</table>
</form>


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

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

方法如下:

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

}
}
return where;

}


说明:我们知道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语句结合分页查询时,跟踪发现对数据的分页是在内存中进行的(这实在太可怕了!!!)。

以上言论纯属本人言论,如有不妥或者错误的地方欢迎指正,同时在下篇博客我将给出以上两个问题的解决方案。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐