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

时间:2024-05-10 19:29:47

目录

关于数据感应

BaseDataList 类

范例运行环境

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.****.net/download/michaelline/89235824

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