动态指定任意类型的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控件,它可以节省很多的开发时间。

(0)

相关推荐

  • 在ASP.NET 2.0中操作数据之六:编程设置ObjectDataSource的参数值

    导言 正如我们在上一节的教程中所看到的,有很多可供选择的方式把参数的值传递到OjbectDataSource的方法里.假如参数值是采用硬编码方式,来源于页面上的一个Web控件,又或者其他可被数据源Parameter对象读取的源,那么这个值可以绑定到输入参数而不需要写一行的代码. 然而有些时候,参数值来自某些在数据源的内置Parameter对象里还没有计算出来的源.假如我们的站点支持我们的考虑那么我们也许希望参数基于当前登录用户.又或者我们在参数传送到ObjectDataSource的隐含对象的方

  • 在ASP.NET 2.0中操作数据之四:使用ObjectDataSource展现数据

    在完成了应用程序架构和页面的设计后,我们可以开始探讨如何实现多种多样的普通数据到报表展现的任务.前面我们已经了解到如何在从数据访问层和业务逻辑层绑定数据到ASP.NET页面上的数据控件.在ASP.NET 1.x应用程序中,通过对数据控件的DataSource属性赋值然后调用控件的DataBind()方法从而实现数据展现的方式在ASP.NET 2.0应用程序中可以继续使用.然而,ASP.NET 2.0的数据源控件提供了一种新的方式,使用这些控件可以让你轻松从上文中创建的业务逻辑层中进行数据绑定,甚

  • gridview+objectdatasource+aspnetpager整合实例

    前台代码: 复制代码 代码如下: <asp:GridView ID="viewIShow" runat="server" DataSourceID="ObjectDataSource1"                    AllowPaging="True" AutoGenerateColumns="False"                    OnRowCommand="view

  • 在ASP.NET 2.0中操作数据之二:创建一个业务逻辑层

    导言 本教程的第一节所描述的数据访问层(Data Access Layer,以下简称为DAL)已经清晰地将表示逻辑与数据访问逻辑区分开了.不过,即使DAL将数据访问的细节从表示层中分离出来了,可它却不能处理任何的业务规则.比如说,我们可能不希望产品表中那些被标记为"停用"的产品的"分类编号"或"供应商编号"被更新:我们还可能需要应用一些资历规则,比如说我们都不希望被比自己的资历还要浅的人管理.另外一个比较常见的情况就是授权,比如说只有那些具有特殊

  • ASP.NET中 ObjectDataSource控件的DataObjectTypeName属性

    一.ObjectDataSource 控件说明 获取或设置某个类的名称,ObjectDataSource 控件将该类用于更新.插入或删除数据操作中的参数,而不是从数据绑定控件传递个别的值. 您不用指定传递给 Update.Insert 和 Delete 方法的多个参数,而是可以创建一个累计多个数据字段值的对象.仅给方法传递这一个对象,而不是多个参数. 绑定到数据绑定控件的 ObjectDataSource 控件的默认行为是,数据绑定控件为数据源中的每个参数创建一个 Parameter 对象.如果

  • 在ASP.NET 2.0中操作数据之一:创建一个数据访问层

    导言 作为web开发人员,我们的生活围绕着数据操作.我们建立数据库来存储数据,写编码来访问和修改数据,设计网页来采集和汇总数据.本文是研究在ASP.NET 2.0中实现这些常见的数据访问模式之技术的长篇系列教程的第一篇.我们将从创建一个软件框架开始,这个框架的组成部分包括一个使用强类型的DataSet的数据访问层(DAL),一个实施用户定义的业务规则的业务逻辑层(BLL),以及一个由共享页面布局的ASP.NET网页组成的表现层.在打下这个后端的基础工作之后,我们将开始转向报表,示范如何显示,汇总

  • 在ASP.NET 2.0中操作数据之五:声明参数

    导言 在上一章的教程中,我们看了GridView.DetailsView和FormView绑定到OjbectDataSource控件显示数据,ObjectDataSource调用了类ProductsBLL的GetProducts()方法.方法GetProducts()返回一个有Northwind数据库的Products表的所有记录组成的强类型数据表.类ProductsBLL还包含了其它返回部分数据的方法:GetProductByProductID(productID),GetProductsBy

  • asp.net 使用ObjectDataSource控件在ASP.NET中实现Ajax真分页

    ListView控件本身并没有分页功能,不过借助于ASP.NET中新增加的DataPager控件,我们可以非常方便地对ListView中的数据设置分页,这几乎不需要开发人员写一行代码,将ListView控件放到页面上,设置好布局和DataSource,然后再添加一个DataPager控件,将它的PagedControlID属性设置成ListView的ID,PageSize中设置每页要显示的数据条数,然后在Fields中设置好分页的样式(当然你完全可以不用去管样式,ASP.NET会根据内置的样式来

  • 在ASP.NET 2.0中操作数据之三:创建母版页和站点导航

    导言 通常,用户友好的个性化站点都有着一致的,站点统一的页面布局和导航体系.Asp.net 2.0引入的两个新特性给我们在统一站点的页面布局和站点导航上提供了简单而有效的工具,它们是母板页和站点导航.母板页允许开发者创建统一的站点模板和指定的可编辑区域.这样,aspx页面只需要给模板页中指定的可编辑区域提供填充内容就可以了,所有在母板页中定义的其他标记将出现在所有使用了该母板页的aspx页面中.这种模式允许开发者可以统一的管理和定义站点的页面布局,因此可以容易的得到拥有统一的视觉和感觉的页面并且

  • 动态指定任意类型的ObjectDataSource对象的查询参数

    ObjectDataSource在使用时需要事先指定查询方法SelectMethod(其实还有InsertMethod,UpdateMethod和DeleteMethod),TypeName和DataObjectTypeName,然后我们只需要编写好SelectMethod方法的实现,如果需要分页,那么还要指定MaximumRwosParameterName属性和StartRowIndexParameterName,然后在SelectMethod方法中加上相应的参数,当然,SelectCount

  • PHP动态地创建属性和方法, 对象的复制, 对象的比较,加载指定的文件,自动加载类文件,命名空间

    PHP前言: •动态地创建属性和方法 •对象的复制 •对象的比较 •加载指定的文件 •自动加载类文件 •命名空间 示例 1.类的相关知识点 3(动态地创建属性和方法) class/class3.php <?php /** * 类的相关知识点 3(动态地创建属性和方法) */ // 用于演示如何动态地创建属性(这就是 php 中所谓的重载) class Class1 { // __set 魔术方法,当设置的属性不存在或者不可访问(private)时就会调用此函数 public function _

  • ASP.NET Core MVC如何实现运行时动态定义Controller类型

    昨天有个朋友在微信上问我一个问题:他希望通过动态脚本的形式实现对ASP.NET Core MVC应用的扩展,比如在程序运行过程中上传一段C#脚本将其中定义的Controller类型注册到应用中,问我是否有好解决方案.我当时在外边,回复不太方便,所以只给他说了两个接口/类型:IActionDescriptorProvider和ApplicationPartManager.这是一个挺有意思的问题,所以回家后通过两种方案实现了这个需求.源代码从这里下载. 一.实现的效果 我们先来看看实现的效果.如下所

  • Go语言使用sort包对任意类型元素的集合进行排序的方法

    本文实例讲述了Go语言使用sort包对任意类型元素的集合进行排序的方法.分享给大家供大家参考.具体如下: 使用sort包的函数进行排序时,集合需要实现sort.Inteface接口,该接口中有三个方法: 复制代码 代码如下: // Len is the number of elements in the collection.  Len() int  // Less reports whether the element with  // index i should sort before t

  • 基于python实现删除指定文件类型

    Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言. Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构. Python 是一种解释型语言: 这意味着开发过程中没有了编译这个环节.类似于PHP和Perl语言. Python 是交互式语言: 这意味着,您可以在一个 Python 提示符 >>> 后直接执行代码. Python 是面向对象语言: 这意味着Python支持面向对象的风格或代码封

  • 详解php 使用Callable Closure强制指定回调类型

    详解php 使用Callable Closure强制指定回调类型 如果一个方法需要接受一个回调方法作为参数,我们可以这样写 <?php function testCallBack($callback){ call_user_func($callback); } function callback(){ echo 'do sth callback'; } testCallBack('callback'); ?> 但我们不能确定回调方法是否可以调用,因此需要做很多额外的工作去检查这个回调方法是否可

  • PHP Callable强制指定回调类型的方法

    如果一个方法需要接受一个回调方法作为参数,我们可以这样写 <?php function dosth($callback){ call_user_func($callback); } function callback(){ echo 'do sth callback'; } dosth('callback'); ?> 输出: do sth callback 但我们不能确定回调方法是否可以调用,因此需要做很多额外的工作去检查这个回调方法是否可以调用. 有什么更好的方法可以判断回调方法是否可调用?

  • JAVA利用泛型返回类型不同的对象方法

    有时需要在方法末尾返回类型不同的对象,而return 语句只能返回一个或一组类型一样的对象.此时就需要用到泛型. 首先先解释个概念, 元组:它是将一组对象直接打包存储于其中的一个单一对象,这个容器对象允许读取其中元素,但不能修改. 利用泛型创建元组 public class ReturnTwo<A,B> { public final A first; public final B second; public ReturnTwo(A a,B b) { first = a; second = b

  • 动态改变ASP.net页面标题和动态指定页面样式表的方法

    如果需要让asp.net应用程序对用户留有一定有自定义空间,例如用户要对页面使用自己定义的样式表或标题,可以使用下面的方法来动态指定: 首先对ASPX文件中<HEAD>中的页面标题和样式表进行修改 Visual Studio 生成的代码: <title>WebForm1</Title> <LINK ref="stylesheet" type="text/css" href="control.css">

  • JS控制网页动态生成任意行列数表格的方法

    本文实例讲述了JS控制网页动态生成任意行列数表格的方法.分享给大家供大家参考.具体分析如下: 这是一个非常简单使用的JS在线生成表格的代码效果 通过JS功能代码,直接输入行数和列数就可以自动生成你需要的表格 当然你也可以扩展JS代码实现生成文字的各种形式 复制代码 代码如下: <html> <head> <title>Js动态生成表格</title> <style type="text/css"> table{font-siz

随机推荐