引言:
我们在做项目开发的过程中,经常会遇到把许多条目的信息的选择情况记录到用户的相关设置当中问题,比较笨的办法是每一个条目对应用户设置表中的一个属性字段,但这样的设计似乎扩展性很差,效率也好不到哪里去,这里提供一种快速存储N条记录的方案,即用一个整型数据来记录条目的选择状态。
内容:
一、表结构:
两个Table
Item 项目表
Key: ID
Field name
Type
Length
Default
Description
ID
int
4
ID(自动编号)
ItemName
Nvarchar
50
0
条目名称
UserInfo 用户信息表
Key: UserID
Field name
Type
Length
Default
Description
UserID
int
4
ID(自动编号)
ItemRecord
int
4
0
条目选择记录
一点说明:我们的目的就是要把用户对Item中所有的记录的选择情况进行记录,经过一定的处理存储到ItemRecord中。
二、数据层类:
四个:QuickItem、QuickItemCollection、UserInfo、UserInfoCollection
一点说明:
1、 QuicItem:对条目信息进行处理的类,包含四种方法,即对数据的添、删、改、读。
2、 QuickItemCollection:这是个查询类,根据一定条件读取条目的集合。
3、 UserInfo:对用户信息进行处理的类,包含四种方法,即对数据的添、删、改、读。
4、 UserInfoCollection:这是个查询类,根据一定条件读取用户信息的集合。
三、表示层调用处理:
//取得个人选中项目的信息
UserInfo ui = new UserInfo();
ui.ID=1;
ui.GetInfoByID();
int itemRecord=ui.ItemRecord;
//取得所有项目的ID数组
QuickItemCollection qic = new QuickItemCollection();
qic.GetAllInfo();
int qicCount=qic.Count;
string itemIDArrayString=null;
for(int i=0;i<qicCount;i++)
{
itemIDArrayString+=","+qic[i].ID;
}
itemIDArrayString=itemIDArrayString.Substring(1,itemIDArrayString.Length-1);
char[] dot = new char[]{','};
string[] itemIDArray = itemIDArrayString.Split(dot);
//调用方法返回选中的项目的ID数组
string [] selectItemArray=SelectItemArray(itemIDArray,itemRecord);
一点说明:上面这段代码就是读取条目信息和个人设置进行相应的处理的,SelectItemArray是个私有方法,代码如下:
#region 取得选中项目记录集
/// <summary>
/// 取得选中项目记录集
/// </summary>
/// <param name="tempItemIDarray">所有项目记录集</param>
/// <param name="tempItemRecord">项目选择信息</param>
/// <returns>选中项目记录集</returns>
private string[] SelectItemArray(string[] tempItemIDarray,int tempItemRecord)
{
//项目的ID数组元素个数
int itemIDarrayCount=tempItemIDarray.Length;
//将整形记录转化成二进制
string itemRecordString = Convert.ToString(tempItemRecord,2);
//存储的选择信息位个数
int itemRecordStringCount=itemRecordString.Length;
//需要补0的个数
int addZeroCount=itemIDarrayCount-itemRecordStringCount;
//开始往高位补0
for(int i=0;i<addZeroCount;i++)
{
itemRecordString="0"+itemRecordString;
}
//选中ID字符串
string selectItemString=null;
//开始匹配选中项
int count=itemRecordString.Length;
for(int j=0;j<count;j++)
{
if(Int32.Parse(itemRecordString.Substring(j,1))==1)
{
selectItemString+=","+tempItemIDarray[j];
}
}
//剃除第一个","
selectItemString=selectItemString.Substring(1,selectItemString.Length-1);
char[] dot = new char[]{','};
//返回选中的项目ID数组
return selectItemString.Split(dot);
}
#endregion
一点说明:
如果你还没有看明白上面的代码,那么现在就看我来解释给你听。这里的方案其实是利用了二进制数据位的“0”“1”来标识是否选中某条目的,如果选中即为“1”,每一个条目都对应一个二进制位,如果Item中有五条数据,那么全是“11111”,这样的二进制数据,如果我们想选中第一条、第二条和第五条数据,那么对应的二进制代码表示为“10101”,然后我们把这个二进制数据转化成十进制数据就是:16+0+4+0+1=21,如此种种我们可以通过转换记录各种组合的记录。这里要注意的是新增条目的问题,如果现在条目变成了七条怎么办?不用担心,变成了七条,那么就有七个位“1111111”,那么这个时候我原来的选中三条数据是不要变化的,这增加的两个位是增加在高位上的,即现在的存储表示变成了“0010101”,就是:0+0+16+0+4+0+1=21,数值是没有变化的。一般情况下我们是添加条目,很少有减少条目的情况,如果要减少条目,肯定要另外写程序来重置ItemRecord的值的。
那么用户重新选择条目后,如何重置ItemRecord值呢?下面听我慢慢道来,像这种多选的条目一般都会由CheckBoxList绑定出来进行选择操作的,我们也就是对这个对象的元素选中情况进行处理,代码片段如下:
int itemCount=CheckBoxList_Item.Items.Count;
for(int i=0;i<itemCount;i++)
{
if(CheckBoxList_Item.Items[i].Selected)
{
itemSelect=itemSelect+"1";
}
else
{
itemSelect=itemSelect+"0";
}
}
int itemRecord=Convert.ToInt32(itemSelect, 2);
一点说明:首先获得条目的个数,然后做循环,判断是否选中,如果选中则相应的位值为“1”,否则为“0”,组合出来二进制字符串然后再进行个进制转换,然后再入库就一切搞定了。
是不是很方便呢?不仅方便这种存储效率是非常高的,如果你有几百个条目要选择,这种方案便是一个不错的选择,不过,你如果真搞几百个条目让别人选,除非是被逼无奈的应付考试,否则一定会遭遇强烈的鄙视的,谁有耐心去做这个选择嘛,哈哈!
不要急,再给一个提醒看看,千万不要把顺序搞错了,绑定CheckBoxList的时候,按照DESC的顺序来绑定元素列表,不然,吼吼……
本篇没有提供完整代码,如果需要完整代码或者技术探讨的机会,可以通过下面的联系方式找偶,MSN:yubo@x263.net,拒绝闲聊。