動(dòng)態(tài)指定任意類型的ObjectDataSource對(duì)象的查詢參數(shù)
更新時(shí)間:2009年11月24日 20:19:52 作者:
我在使用ObjectDataSource控件在ASP.NET中實(shí)現(xiàn)Ajax真分頁 一文中詳細(xì)介紹過如何使用ObjectDataSource和ListView實(shí)現(xiàn)數(shù)據(jù)綁定和分頁功能。事實(shí)上,采用ObjectDataSource和ListView相結(jié)合,可以減少我們很多的開發(fā)任務(wù)。
ObjectDataSource在使用時(shí)需要事先指定查詢方法SelectMethod(其實(shí)還有InsertMethod,UpdateMethod和DeleteMethod),TypeName和DataObjectTypeName,然后我們只需要編寫好SelectMethod方法的實(shí)現(xiàn),如果需要分頁,那么還要指定MaximumRwosParameterName屬性和StartRowIndexParameterName,然后在SelectMethod方法中加上相應(yīng)的參數(shù),當(dāng)然,SelectCountMethod屬性也是要指定的,并且參數(shù)簽名必須和SelectMethod方法的參數(shù)簽名相同。這些我在前面那篇文章中都有詳細(xì)的介紹。這里我想說一下如何動(dòng)態(tài)指定ObjectDataSource對(duì)象的查詢參數(shù),例如我們使用ObjectDataSource對(duì)象來綁定ListView數(shù)據(jù)源,一般查詢參數(shù)都是事先通過SelectParameter確定好并傳入給ObjectDataSource的,如果我們想實(shí)現(xiàn)根據(jù)用戶選擇的條件進(jìn)行查詢,在頁面回傳的時(shí)候?qū)⒉樵儣l件傳遞給ObectDataSource對(duì)象,并且允許隨意指定查詢參數(shù)的數(shù)據(jù)類型,怎么實(shí)現(xiàn)呢?
其實(shí)ObjectDataSource參數(shù)是可以指定查詢參數(shù)的,它有很多種不同類型的查詢參數(shù),如ControlParameter,CookieParameter,F(xiàn)ormParameter,ProfileParameter,QueryStringParameter,SessionParameter等。由于不能在ObjectDataSource的SelectMethod方法中引入頁面元素,如文本框的值,下拉列表的值,這是因?yàn)镺bjectDataSource在初始化并指定SelectMethod方法時(shí)頁面上的其它元素還沒有完成初始化,此時(shí)引用頁面上的這些元素將會(huì)引發(fā)空引用的異常。正確的方法是通過ObjectDataSource的查詢參數(shù)來解決此類問題,如我們可以使用QueryStringParameter通過頁面的url來傳遞參數(shù),還可以使用CookieParameter通過客戶端的Cookie傳遞參數(shù),使用SessionParameter通過服務(wù)端的Session來傳遞參數(shù)。不過這些參數(shù)都有問題,QueryStringParameter只能傳遞字符串類型的參數(shù),復(fù)雜類型的參數(shù)很難實(shí)現(xiàn);CookieParameter收到客戶端Cookie的限制,也不太理想;SessionParameter有些夸張,我不能因?yàn)橛脩粝胪瓿梢淮魏?jiǎn)單的查詢操作就在服務(wù)器上存放一大堆Session吧?
看來使用ControlParameter是比較理想的,畢竟用戶都是通過頁面上的控件來指定查詢條件的,而程序也正是通過頁面上的控件才得到用戶所指定的查詢條件的,這個(gè)是比較符合邏輯的。下面我們就來看看如何通過ControlParameter來實(shí)現(xiàn)ObjectDataSource的查詢參數(shù)動(dòng)態(tài)指定。
<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>
給定的代碼不是完整的代碼,因?yàn)槲以诶又惺褂玫腘Hibernate作為數(shù)據(jù)持久層,這樣我不太方便講整個(gè)可執(zhí)行代碼都貼出來,還望大家能諒解!不過從上面的代碼中可以看出,我們可以直接在ObjectDataSource的標(biāo)記中引入SelectParameters參數(shù)列表,將要作為查詢參數(shù)的控件依次通過ControlParameter標(biāo)記給出。其中ControlID為指定的控件ID,PropertyName為控件取值的屬性名稱,Name為參數(shù)名稱,這個(gè)與SelectMethod中的查詢參數(shù)簽名相對(duì)應(yīng)。
下面是服務(wù)端代碼。這里順便給出了DeleteMethod方法的實(shí)現(xiàn),代碼中引入了其它的類庫,讀者只需看明白其中的道理即可!
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("刪除失敗!請(qǐng)查看數(shù)據(jù)庫日志以確定失敗原因。");
}
}
public int CountAll(string cate, string area, string begintime, string endtime)
{
return Convert.ToInt32(ViewState["ITEMCOUNT"] ?? 0);
}
CountAll的參數(shù)簽名必須和SelectDatas的參數(shù)簽名相同。在這里,查詢參數(shù)的數(shù)據(jù)類型是NHibernate的ICriterion數(shù)組,在SelectDatas中首先會(huì)判斷指定控件的值是否為空,不為空則構(gòu)建ICriterion查詢數(shù)組,然后將參數(shù)傳遞給底層代碼進(jìn)行數(shù)據(jù)查詢。在這里沒有直接引用頁面上的控件,而是通過查詢參數(shù)來獲取的值。這樣,當(dāng)用戶指定查詢或者查看全部數(shù)據(jù)時(shí),我們幾乎不用做任何事情。
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的數(shù)據(jù)源重新指向ObjectDataSource,以實(shí)現(xiàn)數(shù)據(jù)綁定的“刷新”效果。btDoQuery_Click只需要執(zhí)行一下RefreshData方法即可,因?yàn)轫撁嫔峡丶闹狄呀?jīng)通過ControlParameter查詢參數(shù)傳遞給ObjectDataSource了,我們沒有其它的東西需要處理。別忘了!服務(wù)器端控件的值在默認(rèn)情況下是可以回傳的。btAll_Click是查詢?nèi)繑?shù)據(jù),此時(shí)我們只需要將控件中的值清空,然后重新執(zhí)行RefreshData方法即可。
是不是很簡(jiǎn)單?。科鋵?shí)ObjectDataSource控件的功能還是很強(qiáng)大的,以后綁定頁面數(shù)據(jù),尤其是帶有分頁效果時(shí)建議多用ObjectDataSource控件,它可以節(jié)省很多的開發(fā)時(shí)間。
其實(shí)ObjectDataSource參數(shù)是可以指定查詢參數(shù)的,它有很多種不同類型的查詢參數(shù),如ControlParameter,CookieParameter,F(xiàn)ormParameter,ProfileParameter,QueryStringParameter,SessionParameter等。由于不能在ObjectDataSource的SelectMethod方法中引入頁面元素,如文本框的值,下拉列表的值,這是因?yàn)镺bjectDataSource在初始化并指定SelectMethod方法時(shí)頁面上的其它元素還沒有完成初始化,此時(shí)引用頁面上的這些元素將會(huì)引發(fā)空引用的異常。正確的方法是通過ObjectDataSource的查詢參數(shù)來解決此類問題,如我們可以使用QueryStringParameter通過頁面的url來傳遞參數(shù),還可以使用CookieParameter通過客戶端的Cookie傳遞參數(shù),使用SessionParameter通過服務(wù)端的Session來傳遞參數(shù)。不過這些參數(shù)都有問題,QueryStringParameter只能傳遞字符串類型的參數(shù),復(fù)雜類型的參數(shù)很難實(shí)現(xiàn);CookieParameter收到客戶端Cookie的限制,也不太理想;SessionParameter有些夸張,我不能因?yàn)橛脩粝胪瓿梢淮魏?jiǎn)單的查詢操作就在服務(wù)器上存放一大堆Session吧?
看來使用ControlParameter是比較理想的,畢竟用戶都是通過頁面上的控件來指定查詢條件的,而程序也正是通過頁面上的控件才得到用戶所指定的查詢條件的,這個(gè)是比較符合邏輯的。下面我們就來看看如何通過ControlParameter來實(shí)現(xiàn)ObjectDataSource的查詢參數(shù)動(dòng)態(tài)指定。
復(fù)制代碼 代碼如下:
<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>
給定的代碼不是完整的代碼,因?yàn)槲以诶又惺褂玫腘Hibernate作為數(shù)據(jù)持久層,這樣我不太方便講整個(gè)可執(zhí)行代碼都貼出來,還望大家能諒解!不過從上面的代碼中可以看出,我們可以直接在ObjectDataSource的標(biāo)記中引入SelectParameters參數(shù)列表,將要作為查詢參數(shù)的控件依次通過ControlParameter標(biāo)記給出。其中ControlID為指定的控件ID,PropertyName為控件取值的屬性名稱,Name為參數(shù)名稱,這個(gè)與SelectMethod中的查詢參數(shù)簽名相對(duì)應(yīng)。
下面是服務(wù)端代碼。這里順便給出了DeleteMethod方法的實(shí)現(xiàn),代碼中引入了其它的類庫,讀者只需看明白其中的道理即可!
復(fù)制代碼 代碼如下:
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("刪除失敗!請(qǐng)查看數(shù)據(jù)庫日志以確定失敗原因。");
}
}
public int CountAll(string cate, string area, string begintime, string endtime)
{
return Convert.ToInt32(ViewState["ITEMCOUNT"] ?? 0);
}
CountAll的參數(shù)簽名必須和SelectDatas的參數(shù)簽名相同。在這里,查詢參數(shù)的數(shù)據(jù)類型是NHibernate的ICriterion數(shù)組,在SelectDatas中首先會(huì)判斷指定控件的值是否為空,不為空則構(gòu)建ICriterion查詢數(shù)組,然后將參數(shù)傳遞給底層代碼進(jìn)行數(shù)據(jù)查詢。在這里沒有直接引用頁面上的控件,而是通過查詢參數(shù)來獲取的值。這樣,當(dāng)用戶指定查詢或者查看全部數(shù)據(jù)時(shí),我們幾乎不用做任何事情。
復(fù)制代碼 代碼如下:
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的數(shù)據(jù)源重新指向ObjectDataSource,以實(shí)現(xiàn)數(shù)據(jù)綁定的“刷新”效果。btDoQuery_Click只需要執(zhí)行一下RefreshData方法即可,因?yàn)轫撁嫔峡丶闹狄呀?jīng)通過ControlParameter查詢參數(shù)傳遞給ObjectDataSource了,我們沒有其它的東西需要處理。別忘了!服務(wù)器端控件的值在默認(rèn)情況下是可以回傳的。btAll_Click是查詢?nèi)繑?shù)據(jù),此時(shí)我們只需要將控件中的值清空,然后重新執(zhí)行RefreshData方法即可。
是不是很簡(jiǎn)單?。科鋵?shí)ObjectDataSource控件的功能還是很強(qiáng)大的,以后綁定頁面數(shù)據(jù),尤其是帶有分頁效果時(shí)建議多用ObjectDataSource控件,它可以節(jié)省很多的開發(fā)時(shí)間。
您可能感興趣的文章:
- asp.net 使用ObjectDataSource控件在ASP.NET中實(shí)現(xiàn)Ajax真分頁
- gridview+objectdatasource+aspnetpager整合實(shí)例
- ASP.NET中 ObjectDataSource控件的DataObjectTypeName屬性
- 在ASP.NET 2.0中操作數(shù)據(jù)之一:創(chuàng)建一個(gè)數(shù)據(jù)訪問層
- 在ASP.NET 2.0中操作數(shù)據(jù)之二:創(chuàng)建一個(gè)業(yè)務(wù)邏輯層
- 在ASP.NET 2.0中操作數(shù)據(jù)之三:創(chuàng)建母版頁和站點(diǎn)導(dǎo)航
- 在ASP.NET 2.0中操作數(shù)據(jù)之四:使用ObjectDataSource展現(xiàn)數(shù)據(jù)
- 在ASP.NET 2.0中操作數(shù)據(jù)之五:聲明參數(shù)
- 在ASP.NET 2.0中操作數(shù)據(jù)之六:編程設(shè)置ObjectDataSource的參數(shù)值
相關(guān)文章
ADO.NET 讀取EXCEL的實(shí)現(xiàn)代碼((c#))
經(jīng)常需要在數(shù)據(jù)庫與Execl之間互導(dǎo)數(shù)據(jù)。net時(shí)代,ADO.NET可以使用使用Microsoft.Jet.OleDb訪問訪問Excel,網(wǎng)上已經(jīng)有很多類似的資源,最典型也是最簡(jiǎn)單的可能如下:(asp.net環(huán)境)2012-12-12asp.net(c#)有關(guān) Session 操作的幾個(gè)誤區(qū)
asp.net(c#)有關(guān) Session 操作的幾個(gè)誤區(qū)...2007-06-06C#中Dictionary幾種遍歷的實(shí)現(xiàn)代碼
C#中Dictionary幾種遍歷的實(shí)現(xiàn)代碼,需要的朋友可以參考一下2013-02-02.NET開發(fā)實(shí)現(xiàn)一個(gè)微信跳一跳的輔助程序
最近比較火的小游戲就是微信跳一跳了,下面這篇文章主要給大家介紹了關(guān)于如何利用.NET開發(fā)實(shí)現(xiàn)一個(gè)微信跳一跳輔助程序的相關(guān)資料,利用此輔助可以輕松的實(shí)現(xiàn)高分,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01.Net結(jié)合JS實(shí)現(xiàn)URL編碼與解碼
這篇文章介紹了.Net結(jié)合JS實(shí)現(xiàn)URL編碼與解碼的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03asp.net使用Socket.Send發(fā)送信息及Socket.SendFile傳輸文件的方法
這篇文章主要介紹了asp.net使用Socket.Send發(fā)送信息及Socket.SendFile傳輸文件的方法,結(jié)合實(shí)例形式分析了asp.net基于socket實(shí)現(xiàn)信息與文件傳輸?shù)南嚓P(guān)技巧,需要的朋友可以參考下2016-06-06ASP.NET Core AutoWrapper 自定義響應(yīng)輸出實(shí)現(xiàn)
這篇文章主要介紹了ASP.NET Core AutoWrapper 自定義響應(yīng)輸出實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08