动态指定任意类型的ObjectDataSource对象的查询参数_实用技巧

ObjectDataSource在使用时需要事先指定查询方法SelectMethod(其实还有InsertMethod,UpdateMethod和DeleteMethod),TypeName和DataObjectTypeName,然后我们只需要编写好SelectMethod方法的实现,如果需要分页,那么还要指定MaximumRwosParameterName属性和StartRowIndexParameterName,然后在SelectMethod方法中加上相应的参数,当然,SelectCountMethod属性也是要指定的,并且参数签名必须和SelectMethod方法的参数签名相同。这些我在前面那篇文章中都有详细的介绍。这里我想说一下如何动态指定ObjectDataSource对象的查询参数,例如我们使用ObjectDataSource对象来绑定ListView数据源,一般查询参数都是事先通过SelectParameter确定好并传入给ObjectDataSource的,如果我们想实现根据用户选择的条件进行查询,在页面回传的时候将查询条件传递给ObectDataSource对象,并且允许随意指定查询参数的数据类型,怎么实现呢?

  其实ObjectDataSource参数是可以指定查询参数的,它有很多种不同类型的查询参数,如ControlParameter,CookieParameter,FormParameter,ProfileParameter,QueryStringParameter,SessionParameter等。由于不能在ObjectDataSource的SelectMethod方法中引入页面元素,如文本框的值,下拉列表的值,这是因为ObjectDataSource在初始化并指定SelectMethod方法时页面上的其它元素还没有完成初始化,此时引用页面上的这些元素将会引发空引用的异常。正确的方法是通过ObjectDataSource的查询参数来解决此类问题,如我们可以使用QueryStringParameter通过页面的url来传递参数,还可以使用CookieParameter通过客户端的Cookie传递参数,使用SessionParameter通过服务端的Session来传递参数。不过这些参数都有问题,QueryStringParameter只能传递字符串类型的参数,复杂类型的参数很难实现;CookieParameter收到客户端Cookie的限制,也不太理想;SessionParameter有些夸张,我不能因为用户想完成一次简单的查询操作就在服务器上存放一大堆Session吧?

  看来使用ControlParameter是比较理想的,毕竟用户都是通过页面上的控件来指定查询条件的,而程序也正是通过页面上的控件才得到用户所指定的查询条件的,这个是比较符合逻辑的。下面我们就来看看如何通过ControlParameter来实现ObjectDataSource的查询参数动态指定。

复制代码 代码如下:

<asp:ObjectDataSource ID="DataSource" runat="server" SelectMethod="SelectDatas"
TypeName="MilitaryShopWeb.Admin.SystemConfig.SysLog" DataObjectTypeName="MilitaryShopModel.Log" EnablePaging="True"
MaximumRowsParameterName="maxRows" StartRowIndexParameterName="startIndex" SelectCountMethod="CountAll" DeleteMethod="DeleteData">
<SelectParameters>
<asp:ControlParameter ControlID="ddlCate" PropertyName="SelectedValue" Name="cate" />
<asp:ControlParameter ControlID="ddlArea" PropertyName="SelectedValue" Name="area" />
<asp:ControlParameter ControlID="tbBeginTime" PropertyName="Text" Name="begintime" />
<asp:ControlParameter ControlID="tbEndTime" PropertyName="Text" Name="endtime" />
</SelectParameters>
</asp:ObjectDataSource>

  给定的代码不是完整的代码,因为我在例子中使用的NHibernate作为数据持久层,这样我不太方便讲整个可执行代码都贴出来,还望大家能谅解!不过从上面的代码中可以看出,我们可以直接在ObjectDataSource的标记中引入SelectParameters参数列表,将要作为查询参数的控件依次通过ControlParameter标记给出。其中ControlID为指定的控件ID,PropertyName为控件取值的属性名称,Name为参数名称,这个与SelectMethod中的查询参数签名相对应。

  下面是服务端代码。这里顺便给出了DeleteMethod方法的实现,代码中引入了其它的类库,读者只需看明白其中的道理即可!

复制代码 代码如下:

public List<Log> SelectDatas(int startIndex, int maxRows, string cate, string area, string begintime, string endtime)
{
int itemCount;
int pageIndex = 1;
if (startIndex > 0)
{
pageIndex = (startIndex) / PageSize + 1;
}

LogBll bll = new LogBll();
List<ICriterion> query = new List<ICriterion>();
ICriterion[] expression = null;
if (cate != "-1")
{
query.Add(Restrictions.Eq("Logtype", cate));
}
if (area != "-1")
{
query.Add(Restrictions.Eq("Applicationarea", area));
}
if (begintime != null && begintime.Trim().Length > 0)
{
query.Add(Restrictions.Ge("Logtime", DateTime.Parse(begintime.Trim())));
}
if (endtime != null && endtime.Trim().Length > 0)
{
query.Add(Restrictions.Le("Logtime", DateTime.Parse(endtime.Trim())));
}

if (query.Count > 0)
{
expression = query.ToArray();
}

try
{
List<Log> list = bll.GetProducts(expression, pageIndex, maxRows, out itemCount);
ViewState["ITEMCOUNT"] = itemCount;
return list;
}
catch (Exception ex)
{
Log log = new Log(LogType.Error.ToString(), ex.Message, DateTime.Now, ApplicationArea.SysLogManage.ToString(), ex.StackTrace);
ApplicationLog.Write(log);
}

return null;
}

public static void DeleteData(Log obj)
{
try
{
LogBll bll = new LogBll();
bll.Delete(obj.Id);
ScriptHelper.ShowMessage("删除成功!");
}
catch (Exception ex)
{
Log log = new Log(LogType.Error.ToString(), ex.Message, DateTime.Now, ApplicationArea.ProductCategoriesList.ToString(), ex.StackTrace);
ApplicationLog.Write(log);
ScriptHelper.ShowMessage("删除失败!请查看数据库日志以确定失败原因。");
}
}

public int CountAll(string cate, string area, string begintime, string endtime)
{
return Convert.ToInt32(ViewState["ITEMCOUNT"] ?? 0);
}

  CountAll的参数签名必须和SelectDatas的参数签名相同。在这里,查询参数的数据类型是NHibernate的ICriterion数组,在SelectDatas中首先会判断指定控件的值是否为空,不为空则构建ICriterion查询数组,然后将参数传递给底层代码进行数据查询。在这里没有直接引用页面上的控件,而是通过查询参数来获取的值。这样,当用户指定查询或者查看全部数据时,我们几乎不用做任何事情。

复制代码 代码如下:

private void RefreshData()
{
lvList.DataSourceID = DataSource.ID;
}

protected void btDoQuery_Click(object sender, EventArgs e)
{
RefreshData();
}

protected void btAll_Click(object sender, EventArgs e)
{
this.ddlArea.SelectedValue = "-1";
this.ddlCate.SelectedValue = "-1";
this.tbBeginTime.Text = string.Empty;
this.tbEndTime.Text = string.Empty;
RefreshData();
}

  RefreshData方法只是将ListView的数据源重新指向ObjectDataSource,以实现数据绑定的“刷新”效果。btDoQuery_Click只需要执行一下RefreshData方法即可,因为页面上控件的值已经通过ControlParameter查询参数传递给ObjectDataSource了,我们没有其它的东西需要处理。别忘了!服务器端控件的值在默认情况下是可以回传的。btAll_Click是查询全部数据,此时我们只需要将控件中的值清空,然后重新执行RefreshData方法即可。

  是不是很简单啊?其实ObjectDataSource控件的功能还是很强大的,以后绑定页面数据,尤其是带有分页效果时建议多用ObjectDataSource控件,它可以节省很多的开发时间。

时间: 2024-12-03 21:58:14

动态指定任意类型的ObjectDataSource对象的查询参数_实用技巧的相关文章

ASP.NET中application对象的使用介绍_实用技巧

Application对象的应用 1.使用Application对象保存信息 (1).使用Application对象保存信息 Application("键名") = 值 或 Application("键名",值) (2).获取Application对象信息 变量名 = Application("键名") 或:变量名 = Application.Item("键名") 或:变量名 = Application.Get("键

值类型和引用类型的区别深入理解_实用技巧

区别: 1.值类型通常被分配在栈上,它的变量直接包含变量的实例,使用效率比较高. 2.引用类型分配在托管堆上,引用类型的变量通常包含一个指向实例的指针,变量通过该指针来引用实例.3.值类型继承自ValueType(注意:而System.ValueType又继承自System.Object):而引用类型继承自System.Object. 4.值类型变量包含其实例数据,每个变量保存了其本身的数据拷贝(副本),因此在默认情况下,值类型的参数传递不会影响参数本身:而引用类型变量保存了其数据的引用地址,因

Asp.net内置对象之Request对象(概述及应用)_实用技巧

前言:Request对象主要用于获取来自客户端的数据,如用户填入表单的数据.保存在客户端的Cookie等. 一.Request对象概述 1.主要属性    ApplicationPath  获取服务器上asp.net应用程序的虚拟应用程序根路径  Browser  获取有关正在请求的客户端的浏览器功能的信息,该属性值为:HttpBrowserCapabilities对  象  ContentEncoding  获取或设置实体主体的字符集.该属性值为表示客户端的字符集Encoding对象  Con

Asp.net内置对象之Server对象(概述及应用)_实用技巧

一.了解Server对象 Server对象提供对服务器上的方法和属性的访问以及进行HTML编码的功能.这些功能分别由Server对象相应的方法和属性完成. 二.Server对象的常用属性 (1).MachineName(2).ScriptTimeout:属性用于设置脚本程序执行的时间,适当地设置脚本程序的ScriptTimeout可以提高整个Web应用程序的效率.语法如下:Server.ScriptTimeout=time;(以s(秒)为单位) ScriptTimeout属性的最短时间默认为90

Repeater控件动态变更列(Header,Item和Foot)信息实现思路_实用技巧

需求开发一个小报表,显示最近五个月的summary的数量统计,报表会随月份的变化而变化,如下图.第一列[Department]固定,第二至第六列,也就是说Nov 2012 这列会在下月的时候消失,其后的列会向前移,最后一列Mar 2013 会变为Apr 2013. 下图中,最底一行是显示每一列的总数(除第一列外). 为了这个报表,Insus.NET决定使用Repeater控件来实现.难度在于动态显法第二列至第六列的列名,以及绑定数据.最后一行计算总计的,只要完成上面的动态绑定之后,也算不上问题,

Asp.net的应用程序对象和页面生存周期_实用技巧

IIS在接到一个新的http请求后,最终会调用asp.net_isapi.dll的 ISAPI扩展(特指IIS6.0环境,iis7.0的应用程序池默认为集成方式,相对有所变化),然后传递到httpRuntime Pipe(http运行时管道),Asp.Net这时才开始运行(即HttpRunTime是Asp.Net真正的入口),HttpRunTime会为每 个asp.net应用自动创建一个HttpApplication的实例,而该实例中又包含以下属性: 注1 Application -->相当于传

ASP.NET Session对象保持会话使用说明_实用技巧

ASP.NET提供了Session对象,从而允许程序员识别.存储和处理同一个浏览器对象对服务器上某个特定网络应用程序的若干次请求的上下文信息.Session对应浏览器与服务器的同一次对话,在浏览器第一请求网络应用程序的某个页面时,服务器会触发Session_onStart事件:在对话超时或者被关闭的时候会触发Session_onEnd事件.程序员可以在代码中响应这两个事件来处理与同一次对话相关的任务,如开辟和释放该次对话要使用的资源等. 在ASP.NET的程序中要使用Session对象时,必须确

动态组合SQL语句方式实现批量更新的实例_实用技巧

Default.aspx 复制代码 代码如下: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Index.aspx.cs" Inherits="Index" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w

asp.net 获取指定文件夹下所有子目录及文件(树形)_实用技巧

#region 获取指定文件夹下所有子目录及文件(树形)         /****************************************          * 函数名称:GetFoldAll(string Path)          * 功能说明:获取指定文件夹下所有子目录及文件(树形)          * 参    数:Path:详细路径          * 调用示列:          *           string strDirlist = Server.M