关于数据感应
数据感应也即数据捆绑,是一种动态的,Web控件与数据源之间的交互,本文将继续介绍与数据库提取数据并捆绑到 CheckBoxList 类控件为例,另外同时将控件的值保存回数据库的通用方法。
CheckBoxList 类
System.Web.UI.WebControls.CheckBoxList 类是提供了一组可复选的选项集合,每个选项以true或false 表示其选中状态。其使用方法基于 ListControl 类。
更多 CheckBoxList 类的介绍请参照如下链接:
范例运行环境
操作系统: Windows Server 2019 DataCenter
.net版本: .netFramework4.7.1 或以上
开发工具:VS2019 C#
数据提取:在这里我们以MS SQL Server 2016为例
数据源表设计
我们假设要为用户添加角色权限,则需要涉及两个表:
角色字典表
表(sys_chars)用于列出可用的角色,其结构如下:
序号 | 字段名 | 类型 | 说明 | 备注 |
1 | cid | uniqueidentifier | 唯一ID | 用于后续方法使用 |
2 | charname | nvarchar(30) | 角色名称 |
其数据示例如下:
用户角色表
表(sys_UserChars)用于存储用户的可用角色(用户ID+角色ID 唯一),其结构如下:
序号 | 字段名 | 类型 | 说明 | 备注 |
1 | user_cid | uniqueidentifier | 用户ID | 用户的ID值 |
2 | char_cid | uniqueidentifier | 角色名称 | 用记所属的角色ID值 |
其示例数据如下:
AutoValueDBList 方法
原理
我们需要提取 sys_chars (角色字典表) 数据绑定到 CheckBoxList 控件上,用于显示可用的角色名称。绑定后通过 AutoValueDBList 方法的查询模式,从 sys_UserChars (用户角色表)提取数据并与 CheckBoxList 上的项进行比对,存在的则选中。同理,使用 AutoValueDBList 方法的保存模式,则将用户在 CheckBoxList 上的选项逐一保存到 sys_UserChars (用户角色表)里。
设计
AutoValueDBList 方法主要分查询模式和保存模式,在保存模式的情况下返回成功影响的行数,其参数说明如下表:
序号 | 参数名 | 类型 | 说明 |
1 | strConn | string | 对应数据库的连接字符串 |
2 | _object | ListControl | 要感应的 ListControl 类控件,这里泛指 CheckBoxList |
3 | AutoType | string | 两种值可选择,“query” 为查询模式,“save” 为保存模式 |
4 | keyFieldType | string | 连接的目标表的关键字字段类型,如 uniqueidentifier,比如sys_UserChars 中的 user_cid 字段类型 |
5 | linkKeyValue | string | 连接的目标表的关键字段的值,比如sys_UserChars 中的 user_cid 字段的值 |
6 | Tablename | string | 要连接的目标表比如 sys_UserChars |
7 | KeyField | string | 连接的目标表的关键字字段名,比如sys_UserChars 中的字段 “user_cid” |
8 | KeyField2 | string | 连接的目标表的第二关键字字段名,比如sys_UserChars 中的字段 “char_cid” |
9 | CidFieldName | string | 指定连接目标表的唯一标识字段名,这里仅允许使用 uniqueidentifier 的类型字段,如无则默认不参于 insert 操作,设置则表示其值为 newid() |
实现
AutoValueDBList 方法完整代码如下:
public int AutoValueDBList(string strConn,ListControl _object,string AutoType,string keyFieldType,string linkKeyValue,string Tablename,string KeyField,string KeyField2,string CidFieldName) { int rv=-1; SqlDbType type=GetSqlDbType(keyFieldType); SqlConnection Conn = new SqlConnection(strConn ); SqlCommand Cmd = new SqlCommand(); Cmd.Connection = Conn; if(AutoType=="save") { Cmd.CommandText = " delete from "+Tablename+" where "+KeyField+"=@"+KeyField; SqlParameter para1=new SqlParameter("@"+KeyField,type); para1.Value=(keyFieldType.ToLower()=="uniqueidentifier"?(object)(new Guid(linkKeyValue)):(object)linkKeyValue); Cmd.Parameters.Add(para1); try { Conn.Open(); Cmd.ExecuteNonQuery(); Cmd.CommandText = " insert into "+Tablename+"("+KeyField+","+KeyField2+") values(@"+KeyField+",@"+KeyField2+")"; if(CidFieldName!="") { Cmd.CommandText = " insert into "+Tablename+"("+CidFieldName+","+KeyField+","+KeyField2+") values(newid(),@"+KeyField+",@"+KeyField2+")"; } SqlParameter para2=new SqlParameter("@"+KeyField2,type); Cmd.Parameters.Add(para2); int success=0; for(int i=0;i<_object.Items.Count;i++) { string _value=_object.Items[i].Value; if(!_object.Items[i].Selected){continue;} para2.Value=(keyFieldType.ToLower()=="uniqueidentifier"?(object)(new Guid(_value)):(object)_value); int si=Cmd.ExecuteNonQuery(); success+=si; } return success; } catch (Exception ex) { return rv; } finally { Conn.Close(); Conn.Dispose(); } } if(AutoType=="query") { SqlDataReader myDr; Cmd.CommandText = " select "+KeyField2+" from "+Tablename+" where "+KeyField+"=@"+KeyField; SqlParameter para1=new SqlParameter("@"+KeyField,type); para1.Value=(keyFieldType.ToLower()=="uniqueidentifier"?(object)(new Guid(linkKeyValue)):(object)linkKeyValue); Cmd.Parameters.Add(para1); try { Conn.Open(); myDr=Cmd.ExecuteReader(); for(int i=0;i<_object.Items.Count;i++) { _object.Items[i].Selected=false; } rv=0; while(myDr.Read()) { rv++; string _dbkey=myDr[KeyField2].ToString(); for(int i=0;i<_object.Items.Count;i++) { string _value=_object.Items[i].Value; if(_value==_dbkey){ _object.Items[i].Selected=true; } } } } catch (Exception ex) { return rv; } finally { Conn.Close(); Conn.Dispose(); } } return rv; } public SqlDbType GetSqlDbType(String TypeInfo) { TypeInfo=TypeInfo.ToLower(); //Byte if((TypeInfo=="varchar")||(TypeInfo=="system.string")) { return SqlDbType.VarChar; } if((TypeInfo=="bigint")||(TypeInfo=="system.int64")) { return SqlDbType.BigInt; } if((TypeInfo=="binary")||(TypeInfo=="system.byte[]")) { return SqlDbType.Binary; } if((TypeInfo=="bit")||(TypeInfo=="system.boolean")) { return SqlDbType.Bit; } if((TypeInfo=="char")||(TypeInfo=="system.char")) { return SqlDbType.Char; } if((TypeInfo=="datetime")||(TypeInfo=="system.datetime")) { return SqlDbType.DateTime; } if((TypeInfo=="decimal")||(TypeInfo=="system.decimal")) { return SqlDbType.Decimal; } if((TypeInfo=="float")||(TypeInfo=="system.double")) { return SqlDbType.Float; } if(TypeInfo=="image") { return SqlDbType.Image; } if((TypeInfo=="int")||(TypeInfo=="system.int32")) { return SqlDbType.Int; } if((TypeInfo=="money")||(TypeInfo=="system.decimal")) { return SqlDbType.Money; } if(TypeInfo=="nchar") { return SqlDbType.NChar; } if(TypeInfo=="ntext") { return SqlDbType.NText; } if(TypeInfo=="nvarchar") { return SqlDbType.NVarChar; } if((TypeInfo=="real")||(TypeInfo=="system.single")) { return SqlDbType.Real; } if(TypeInfo=="smalldatetime") { return SqlDbType.SmallDateTime; } if((TypeInfo=="smallint")||(TypeInfo=="system.int16")) { return SqlDbType.SmallInt; } if(TypeInfo=="smallmoney") { return SqlDbType.SmallMoney; } if(TypeInfo=="text") { return SqlDbType.Text; } if((TypeInfo=="timestamp")||(TypeInfo=="system.timespan")) { return SqlDbType.Timestamp; } if((TypeInfo=="tinyint")||(TypeInfo=="system.byte")) { return SqlDbType.TinyInt; } if((TypeInfo=="uniqueidentifier")||(TypeInfo=="system.guid")) { return SqlDbType.UniqueIdentifier; } if(TypeInfo=="varbinary") { return SqlDbType.VarBinary; } if(TypeInfo=="variant") { return SqlDbType.Variant; } return SqlDbType.VarChar; }// end GetSqlDbType function
调用示例
初始化数据
假设前端 UI 有 ID 为 CBL 的 CheckBoxList 控件,则调用的示例代码如下:
simpleDataListEx("sqlserver","数据库连接串","select cid, charname from sys_chars", null, "cid", "charname", CBL, false, "", "","");
有关 simpeDataListEx 的使用方法请阅读我的文章《C# Web控件与数据感应之 Control 类》。
启动查询模式
初始化完成后,启动 AutoValueDBList 方法的查询模式,进行比对操作。示例代码如下:
string user_cid_value="1F044A84-9154-466B-9B9F-894282625729"; AutoValueDBList("你的数据库连接串",CBL, "query", "uniqueidentifier", user_cid_value, "sys_userchars", "user_cid", "char_cid");
使用保存模式
当用户重新进行复选操作时,可以将结果提交给数据库进行保存。示例代码如下:
string user_cid_value="1F044A84-9154-466B-9B9F-894282625729"; AutoValueDBList("你的数据库连接串",CBL,"save","uniqueidentifier",user_cid_value,"sys_userchars","user_cid","char_cid","cid");
小结
范例中使用的MS SQL SERVER 数据库,我的下载资源还提供了 Oracle 9i及达梦数据库的驱动链接库,请下载我的资源:
https://download.csdn.net/download/michaelline/89235824
我们可以根据需要改造方法,另外 AutoValueDBList 方法基于 ListControl 类,我们可以根据实际的需要进行使用和改造。感谢您的阅读,希望本文能够对您有所帮助。