C# Web控件与数据感应之 BaseDataList 类

目录

关于数据感应

[BaseDataList 类](#BaseDataList 类)

范例运行环境

[pageview 方法](#pageview 方法)

设计

实现

调用示例

数据源

调用

小结


关于数据感应

数据感应也即数据捆绑,是一种动态的,Web控件与数据源之间的交互,本文将继续介绍以与数据库提取数据并捆绑控件为例,讲解 C# 创建适用于 BaseDataList 类(如DataGrid)的通用分页数据显示方法。

BaseDataList 类

BaseDataList 类是包括如 DataList 、DataGrid服务器控件的基类,本文我们以 DataGrid 服务器控件控件,并结合 MS SQL SERVER 和 达梦数据库,以数据分页的形式,绑定 DataGrid进行显示。

更多 BaseDataList 类的介绍请参照如下链接:

https://learn.microsoft.com/ZH-CN/dotnet/api/system.web.ui.webcontrols.basedatalist?view=netframework-4.8.1&viewFallbackFrom=net-7.0

范例运行环境

操作系统: Windows Server 2019 DataCenter

.net版本:.netFramework4.7.1 或以上

开发工具:VS2019 C#

数据提取:在这里我们以能够支持 MS SQL Server 2016、国产达梦数据 8 的通用数据库内容提取方法为例,生成数据源需要利用ADO.NET 中的数据提供者对象包括IDbConnection、IDbCommand、IDbDataParameter等,如何使用这些对象请参考我的文章:

《C#实现 IDbConnection / IDbCommand 等相关通用数据接口》

pageview 方法

设计

pageview 方法内置了分页函数写法(目前支持 MS SQL Server 2016 和国产达梦8 数据库 ),另外传递SQL关键命令及配置相关参数,将数据源分页感应到指定的BaseDataList 类控件上,其参数说明如下表:

序号

参数名

类型

说明

1

DbServerType

string

目前支持 "oracle"、"dm8",其它字符串均视为 MS SQL Server

2

strConn

string

对应数据库的连接字符串

3

webctls

string[]

对应的信息标签和选择框的ID集合,如果不指定则按默认值处理,即:

webctls[0]="q_pageno"; //当前页

webctls[1]="q_pagecount"; //总页数

webctls[2]="q_recordcount"; //总记录数

webctls[3]="q_pagesize"; //可选择的每页记录数

webctls[4]="q_pageno_label"; //可选择的每页记录数

4

navsender

string

导航按钮的CommandArgument,

nav1 表示首页,nav2 表示上一页,nav3表示下一页,nav4表示最后一页

5

dbgrid

System.Web.UI.WebControls.

BaseDataList

用于捆绑BaseDataList 的控件,如DataGrid

6

DisplayFieldList

string

用于捆绑到 BaseDataList 的控件上的字段列表,以逗号进行分隔

7

SelectedFieldList

string

SQL 查询语句的 select 部分,即查询字段列表,DisplayFieldList 参数是它的子集

8

OrderFieldList

string

SQL 查询语句的 order by 部分,字段以逗号进行分隔

9

FromTableList

string

SQL 查询语句的 from 部分,表名以逗号进行分隔

10

WhereStatements

string

SQL 查询语句的 where 条件部分, 字符串需要书写 where 字样

11

paras

ArrayList

查询条件中的参数对象集合

12

keyfield

string

查询结果集的唯一标识字段,用于统计总数

13

OuterFromTableList

string

是否有用于左、右连接的表名列表

14

OuterWhereStatements

string

用于左、右连接的查询条件

15

movWhereToOuter

bool

是否用左、右连接查询条件替代where查询条件(如果需要)

16

GroupFuncs

ArrayList

一组需要特殊指定的统计变量值,其添加string[]对象,string[0] 存储字段名,string[1]存储变量名

实现

pageview 方法完整代码如下:

public string pageview(string DbServerType,string strConn,string[] webctls,string navsender,System.Web.UI.WebControls.BaseDataList dbgrid,string DisplayFieldList,string SelectedFieldList,string OrderFieldList,string FromTableList,string WhereStatements,ArrayList paras,string keyfield,string OuterFromTableList,string OuterWhereStatements,bool movWhereToOuter,ArrayList GroupFuncs)
{
			
			string[] defaultobj=new string[5];
			defaultobj[0]="q_pageno"; //当前页
			defaultobj[1]="q_pagecount"; //页总数
			defaultobj[2]="q_recordcount"; //总记录数
			defaultobj[3]="q_pagesize"; //可选择的每页记录数
			defaultobj[4]="q_pageno_label"; //可选择的每页记录数
			
			if(webctls==null)
			{
				webctls=defaultobj;
			}
			if(webctls.GetLength(0)<4){
				webctls=defaultobj;
			}
			ObjectEx oe=new ObjectEx();
			oe.RunAt=RunAt;
			oe.FindContainer=FindContainer;
			int _npc=0;
			int _now=1;
			try
			{
				_now=int.Parse(oe.GetBaseClassText(webctls[0]));
				if(oe.GetBaseClassText(webctls[1])!="")
				{
					_npc=int.Parse(oe.GetBaseClassText(webctls[1]));
				}   
			}
			catch(Exception)
			{
				_now=1;
				_npc=1;
				oe.SetBaseClassText(webctls[0],"1");
				oe.SetBaseClassText(webctls[1],"1");
			}
			string navtype=oe.GetBaseClassArg(navsender);
			if(navtype=="nav1")
			{
				_now=1;
			}
			if(navtype=="nav2")
			{
				_now--;
			}
			if(navtype=="nav3")
			{
				_now++;
			}
			if(navtype=="nav4")
			{
				_now=_npc;
			}
			if(navtype=="nav5")
			{
				_now=int.Parse(oe.GetBaseClassText(webctls[0]));
			}
			if(_now>_npc)
			{
				_now=_npc;
			}
			if(_now<1)
			{
				_now=1;
			}
			_now--;
         
            IDbConnection Conn = GetConnection(DbServerType, strConn);
            IDataReader myDr;
			string _countf=keyfield;
			string _pagesize=oe.GetBaseClassList(webctls[3],"Value");
			_pagesize=(_pagesize==""?"50":_pagesize);

			if(movWhereToOuter==true)
			{
				 WhereStatements=WhereStatements.Replace("where 1=1","");
				if(OuterWhereStatements.IndexOf("{0}")==-1)
				{
					OuterWhereStatements+=" "+WhereStatements;
				}
				else
				{
					OuterWhereStatements=string.Format(OuterWhereStatements,WhereStatements);
				}
				WhereStatements="";
			}
		    string groupf="",resultf="",declare="",intolist= "RecordCount";
			if(GroupFuncs!=null)
			{
				for(int i=0;i<GroupFuncs.Count;i++)
				{
					string[] rv=(string[])GroupFuncs[i];
                    if (DbServerType.ToLower() == "dm8")
                    {
                        intolist += "," + rv[1] ;
                        groupf += "," + rv[0];
                        resultf += "," + rv[1] + " " + rv[1];
                        declare += " " + rv[1] + " " + rv[2] + " ";
                    }
                    else
                    {
                        groupf += ",@" + rv[1] + "=" + rv[0];
                        resultf += ",@" + rv[1] + " " + rv[1];
                        declare += " declare @" + rv[1] + " " + rv[2] + " ";
                    }
                }
			}
			string CommandText = "DECLARE    @PageIndex INT "+
				" DECLARE    @PageSize  INT "+
				" DECLARE    @RecordCount INT "+
				" DECLARE    @PageCount INT "+declare+
				"SET @PageIndex="+_now.ToString()+" "+
				"SET @PageSize="+_pagesize+" "+
				"SELECT @RecordCount =COUNT("+_countf+")"+groupf+" FROM "+FromTableList+" "+WhereStatements+" "+
				"SET @PageCount = CEILING(@RecordCount * 1.0 / @PageSize) "+
				" select @recordcount rc,@pagecount pc"+resultf+
				" SELECT "+DisplayFieldList+" FROM "+
				"(SELECT "+SelectedFieldList+","+
				"ROW_NUMBER() OVER (ORDER BY "+OrderFieldList+") AS sn  "+
				"FROM "+FromTableList+" "+WhereStatements+") AS T "+OuterFromTableList+
				" WHERE T.sn > (@PageIndex * @PageSize)  and T.sn <= ((@PageIndex+1) * @PageSize) "+OuterWhereStatements;
            if (DbServerType.ToLower() == "dm8")
            {
                CommandText = "declare PageIndex INT; " +
                    " PageSize  INT; " +
                    " RecordCount INT; " +
                    " PageCount INT; " + declare +
                    "begin SET PageIndex=" + _now.ToString() + "; " +
                    "SET PageSize=" + _pagesize + "; " +
                    "SELECT COUNT(" + _countf + ") " + groupf +" into "+intolist+ " FROM " + FromTableList + " " + WhereStatements + " ;" +
                    "SET PageCount = CEILING(RecordCount * 1.0 / PageSize) ;" +
                    " select recordcount rc,pagecount pc" + resultf +";"+
                    " SELECT " + DisplayFieldList + " FROM " +
                    "(SELECT " + SelectedFieldList + "," +
                    "ROW_NUMBER() OVER (ORDER BY " + OrderFieldList + ") AS sn  " +
                    "FROM " + FromTableList + " " + WhereStatements + ") AS T " + OuterFromTableList +
                    " WHERE T.sn > (PageIndex * PageSize)  and T.sn <= ((PageIndex+1) * PageSize) " + OuterWhereStatements+" ;"+
                    " end;";

            }
			string _info="";
			try
			{
                ArrayList _paras = new ArrayList();
				if(paras!=null)
				{
					for(int i=0;i<paras.Count;i++)
					{
                        if (DbServerType.ToLower() == "dm8") {
                           _paras.Add(paras[i] as DmParameter);
                        }
                        else
                        {
                            _paras.Add((SqlParameter)paras[i]);
                        }
					}
				}
                IDbCommand Cmd = GetCommand(DbServerType, CommandText, _paras, Conn);

				Conn.Open();
                if (DbServerType.ToLower() == "dm8")
                {
                    myDr = Cmd.ExecuteReader() as DmDataReader;
                }
                else
                {
                    myDr = Cmd.ExecuteReader() as SqlDataReader;
                }
                if (myDr.Read())
				{   
					int pc=int.Parse(myDr["pc"].ToString());
					int rc=int.Parse(myDr["rc"].ToString());
					oe.SetBaseClassText(webctls[1],pc.ToString());
					oe.SetBaseClassText(webctls[2],rc.ToString());
					oe.SetBaseClassText(webctls[0],(_now+1).ToString());
					if(webctls.Length>4)
					{
						oe.SetBaseClassText(webctls[4],(_now+1).ToString());
					}
					if(GroupFuncs!=null)
					{
						for(int i=0;i<GroupFuncs.Count;i++)
						{
							string[] rv=(string[])GroupFuncs[i];
							oe.SetBaseClassText(rv[3],myDr[rv[1]].ToString());
						}
					}
				}

				if(myDr.NextResult())
				{
					dbgrid.DataSource=myDr;
					dbgrid.DataBind();
				}
				myDr.Close();
			}
			catch (Exception ex)
			{
				_info=ex.Message;

			}

			finally
			{
				Conn.Close();
				Conn.Dispose();
			}
			return _info;
}//pageview

pageview方法中涉及对控件ID在Page页面的查找 ,及对基类的一些属性如Text进行设置,因此设计了一个 ObjectEx 类,实现一些控件的查找和设置方法,该类设计如下:

序号

成员

类型

说明

1

public System.Web.UI.HtmlControls.HtmlForm RunAt=null;

属性

运行的Form平台,Asp.net中一般只设置一个Form

2

public System.Web.UI.Control FindContainer=null;

属性

要查找的容器,一般设置为Page

3

public string GetBaseClassArg(string webctl)

方法

得到指定ID控件的 CommandArgument

4

public string GetBaseClassList(string webctl,string gettype)

方法

得到指定 ID 的 ListControl 控件的Text或Value值,gettype 参数值可以设置 Text 或 Value

5

public string GetBaseClassText(string webctl)

方法

得到指定ID控件的 Text 属性

6

public void SetBaseClassText(string webctl,string values)

方法

设置指定ID控件的 Text 属性

类代码如下:

public class ObjectEx
{
		public System.Web.UI.HtmlControls.HtmlForm RunAt=null;
		public System.Web.UI.Control FindContainer=null;

		
		public string GetBaseClassArg(string webctl)
		{
			
			System.Web.UI.Control btnctl;
			btnctl=RunAt.FindControl(webctl);
			if(FindContainer!=null)
			{
				btnctl=FindContainer.FindControl(webctl);
			}
			if(btnctl==null)
			{
				return "";
			}
			if(btnctl.GetType()==typeof(System.Web.UI.HtmlControls.HtmlInputButton))
			{
				if(((System.Web.UI.HtmlControls.HtmlInputButton)btnctl).Attributes["CommandArgument"]!=null)
					return ((System.Web.UI.HtmlControls.HtmlInputButton)btnctl).Attributes["CommandArgument"].ToString();
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.Button))
			{
				return ((System.Web.UI.WebControls.Button)btnctl).CommandArgument;
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.ImageButton))
			{
				return ((System.Web.UI.WebControls.ImageButton)btnctl).CommandArgument;
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.LinkButton))
			{
				return ((System.Web.UI.WebControls.LinkButton)btnctl).CommandArgument;
			}
			return "";

		}
		public string GetBaseClassText(string webctl)
		{
			System.Web.UI.Control btnctl;
			btnctl=RunAt.FindControl(webctl);
			if(FindContainer!=null)
			{
				btnctl=FindContainer.FindControl(webctl);
			}
			if(btnctl==null)
			{
				return "";
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.TextBox))
			{
				return ((System.Web.UI.WebControls.TextBox)btnctl).Text;
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.Label))
			{
				return ((System.Web.UI.WebControls.Label)btnctl).Text;
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.Button))
			{
				return ((System.Web.UI.WebControls.Button)btnctl).Text;
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.LinkButton))
			{
				return ((System.Web.UI.WebControls.LinkButton)btnctl).Text;
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.HyperLink))
			{
				return ((System.Web.UI.WebControls.HyperLink)btnctl).Text;
			}
			return "";
		}
		public void SetBaseClassText(string webctl,string values)
		{
			System.Web.UI.Control btnctl;
			btnctl=RunAt.FindControl(webctl);
			if(FindContainer!=null)
			{
				btnctl=FindContainer.FindControl(webctl);
			}
			if(btnctl==null)
			{
				return;
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.TextBox))
			{
				((System.Web.UI.WebControls.TextBox)btnctl).Text=values;
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.Label))
			{
				((System.Web.UI.WebControls.Label)btnctl).Text=values;
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.Button))
			{
				((System.Web.UI.WebControls.Button)btnctl).Text=values;
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.LinkButton))
			{
				((System.Web.UI.WebControls.LinkButton)btnctl).Text=values;
			}
			if(btnctl.GetType()==typeof(System.Web.UI.WebControls.HyperLink))
			{
				((System.Web.UI.WebControls.HyperLink)btnctl).Text=values;
			}
		}
		public string GetBaseClassList(string webctl,string gettype)
		{
			System.Web.UI.Control btnctl;
			btnctl=RunAt.FindControl(webctl);
			if(FindContainer!=null)
			{
				btnctl=FindContainer.FindControl(webctl);
			}
			if(btnctl==null)
			{
				return "";
			}
			return (gettype.ToLower()=="text"?((System.Web.UI.WebControls.ListControl)btnctl).SelectedItem.Text:((System.Web.UI.WebControls.ListControl)btnctl).SelectedItem.Value);
		}
		
		
}//ObjectEx Class

调用示例

数据源

我们以 MS SQL SERVER 为例,提取信息发布系统列表信息,如下图数据显示:

表(wp_infos)设计基本情况如下表:

序号

字段名

类型

说明

1

title

nvarchar(200)

信息标题

2

pub_time

datetime

发布时间

调用

在页面放置一个ID为 dbgrid 的 DataGrid 控件和一系列的导航按钮等控件,前端示例代码如下:

<div align="center" id="panel">
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="border:1px solid #CFE2FF; border-top:2px solid #1A5FC9; background-color:#F7F9FF;" id="table310">
<tr>
 <td align="center"><asp:DataGrid  ID=dbgrid ShowHeader="True"
ShowFooter="False" CellPadding="0" Border="0"  forecolor="black" Runat=server EnableViewState=True /> </td>
</tr>
<tr>
							  <td align="right"><table border="0" width="100%" cellspacing="0" cellpadding="0" id="table314" bgcolor="#EEF4FF">
								<tr>
									<td align="right" valign="middle" style="display:none;">  
							<asp:ImageButton ID=ntop CommandArgument=nav1 OnClick=navpage  ImageUrl="images/nav1.jpg" Visible="false" Runat=server/>
							&nbsp;&nbsp;&nbsp;&nbsp;<asp:ImageButton ID=nbtm CommandArgument=nav4 OnClick=navpage ImageUrl="images/nav4.jpg" Visible="false" Runat=server/><asp:dropdownlist  id="x_pagesize" runat="server" style="font-size:9pt;font-family:宋体"  Visible="false">   
<asp:ListItem Text="10" Value="10" />
<asp:ListItem Text="20" Value="20" selected="true"/>
<asp:ListItem Text="30" Value="30" />
<asp:ListItem Text="40" Value="40" />
<asp:ListItem Text="50" Value="50" />
<asp:ListItem Text="100" Value="100" />
</asp:dropdownlist><asp:ImageButton Text="go" id="gotopage" Visible="false" OnClick=navpage CommandArgument=nav5 ImageUrl="images/nav5.jpg" Runat=server/></td><td width="515" height="30"></td><td valign="middle" width="100" align="right">共计<asp:Label ID=nrc Runat=server/>条记录</td><td valign="middle" width="4"><img src="../images/2012/inner/inner_dg_l.jpg"></td><td valign="middle" width="46" align="center"><asp:Label ID=ngo Text="1" Runat=server/>/<asp:Label ID=npc Runat=server/></td><td valign="middle" align="left" width="135"><asp:ImageButton ID=nprv CommandArgument=nav2 OnClick=navpage ImageUrl="../images/2012/inner/inner_dg_btn_p.jpg" Runat=server/>&nbsp;&nbsp;<asp:ImageButton ID=nnxt CommandArgument=nav3 OnClick=navpage ImageUrl="../images/2012/inner/inner_dg_btn_n.jpg" Runat=server/></td>
							    </tr>
								</table>
                            </td>
						  </tr>
  </table>
</div>

后端调用示例代码如下:

void navpage(Object sender,EventArgs e)
{
 
  string _sql="  title,pub_time";
  string _wherecon="";
  String arg ="";
  try{
     arg=((ImageButton)sender).CommandArgument;
  }catch(Exception xe){
     arg=((LinkButton)sender).CommandArgument;
  }
  string DisplayFieldList="sn 序号,title 标题名称,pub_time 发布时间";
  string SelectedFieldList=_sql;
  string OrderFieldList="pub_time desc";
  string FromTableList="wp_infos";
  string WhereStatements="";
  object[] rv=GetWhere();
  WhereStatements=rv[0].ToString();	   
  string[] webctls=new string[4];
  webctls[0]="ngo";
  webctls[1]="npc";
  webctls[2]="nrc";
  webctls[3]="x_pagesize";

  pageview("sqlserver","您的数据连接串",webctls,((Control)sender).ID,dbgrid,DisplayFieldList,SelectedFieldList,OrderFieldList,FromTableList,WhereStatements,(ArrayList)rv[1],"id");
}
object[] GetWhere(){
  object[] rv=new object[2];
  string WhereStatements=" where 1=1 ";

  ArrayList paras = new ArrayList();
  if(q_title.Text!=""){
       SqlParameter   para2=new   SqlParameter("@title",SqlDbType.NVarChar,200);
	   para2.Value=q_title.Text;
	   paras.Add(para2);
	   WhereStatements+=" and title like @title ";
  }
  if(q_pub_time1.Text!=""){
       SqlParameter   para4=new   SqlParameter("@pub_time1",SqlDbType.DateTime);
	   para4.Value=q_pub_time1.Text;
	   paras.Add(para4);
	   WhereStatements+=" and pub_time>=@pub_time1 ";
  }
  if(q_pub_time2.Text!=""){
       SqlParameter   para5=new   SqlParameter("@pub_time2",SqlDbType.DateTime);
	   para5.Value=q_pub_time2.Text;
	   paras.Add(para5);
	   WhereStatements+=" and pub_time<=@pub_time2 ";
  }
  rv[0]=WhereStatements;
  rv[1]=paras;
  return rv;
  
}

小结

本方法同时适用于达梦8数据库的数据分页技术,我们可以根据自己的实际需要扩充兼容的数据库功能,范例中所需数据库驱动链接库,请下载我的资源:

https://download.csdn.net/download/michaelline/89235824

感谢您的阅读,希望本文能够对您有所帮助。

相关推荐
快乐飒男3 分钟前
C语言基础(结构体)
c语言·开发语言
怒码ing5 分钟前
前端OpenAPI根据后端Swagger自动生成前端接口报错
前端·openapi
勤劳的进取家7 分钟前
利用模拟退火算法求解旅行商问题
开发语言·python
小马超会养兔子13 分钟前
vue2实现答题组件
开发语言·前端·javascript·vue
呆呆在发呆.20 分钟前
计组实验-Bomb Lab -2
java·服务器·前端
笨笨狗吞噬者22 分钟前
为了解决路径问题,我写了一个eslint plugin
前端·javascript·eslint
威威猫的栗子25 分钟前
用 Python Turtle 绘制经典汤姆猫:重温卡通角色的经典魅力
开发语言·python
星辰@Sea35 分钟前
Python 实现对人的行为预测
开发语言·python
Amor风信子1 小时前
华为OD机试真题---机房布局
java·开发语言·数据结构·算法·华为od
星霜旅人1 小时前
Python的基础知识
开发语言·python·numpy