一、权限设置
第一步, 先建立一个枚举表示所有的权限管理操作,接下来是权限的运算等。
常用的位运算主要有与(&), 或(|)和非(~), 比如:
1 & 0 = 0, 1 | 0 = 1, ~1 = 0
在设计权限时, 我们可以把权限管理操作转换为C#位运算来处理.
第一步, 先建立一个枚举表示所有的权限管理操作:
[Flags]
public enum Permissions
{
Insert = 1,
Delete = 2,
Update = 4,
Query = 8
}
[Flags]表示该枚举可以支持C#位运算, 而枚举的每一项值, 我们用2的n次方来赋值, 这样表示成二进制时刚好是1 = 0001, 2 = 0010, 4 = 0100, 8 = 1000等, 每一位表示一种权限, 1表示有该权限, 0表示没有.
接下来是权限的运算:
1. 权限的加法, 使用与运算来实现. 我们知道, 0001 | 0100 = 0101, 这样就表示同时具有第一位和第三位的权限管理了, 枚举表示为:
Permissions per = Permissions.Insert | Permissions.Update
2. 权限的减法, 使用与运算+非运算来实现, 如上面要去掉Insert权限, 操作为:
Permissions per &= ~Permissions.Insert即是 0101 & ~0001 = 0101 & 1110 = 0100
3. 权限的判断, 使用与运算, 当判断用一用户是否具有该操作权限时, 要把用户的的权限与操作权限进行与运算, 如果得到的结果仍是操作权限管理, 则表示用户具有该权限:
Permissions per = Permissions.Insert | Permissions.Update;
if(per & PermissionsPermissions.Insert = Permissions.Insert)
{
//有操作权限
}
比较过程为 0101 & 0001 = 0001, 0001的0位用与C#位运算把其它位都置成0, 变成只比较1的这一位.
二、月份的设置
有时候需要在一个数据表里面保存十二个月份中某几个月份的标志
这时候可以使用1个字段来代替12个字段,就要运用到十进制来保存月份的记录,然后通过位运算来进行读取和判断
public enum MonthMask
{
month1= 1,
month2= 2,
month3= 4,
month4= 8
……
}
一个字段保存12个月份的标示,高效,简单
同样的道理,二进制可以用来保存多个标示符,可以运用到很多方面
三、论坛帖子
在SQL Server ,采用1,2,4,8,16.....等用数字标识的状态字段可以进行累加,对存在的几种状态进行组合,从而可形成各种组合状态
例如:一条记录该字段原来的数字是,2,如我们想加上4,则可以用
update t_User set iFlag = iFlag | 4 where UserID = 1
(iFlag 为该字段名)
例2:在加上4之后我们想去掉4怎么办呢,可以这样实现
update t_User set iFlag = iFlag ^4 where UserID = 1
这样就又把4从该记录中去掉了.
如果我们想选择所有为2的记录该怎么做呢,可以这样实现
select * from t_User where iFlag &2 = 2
SQL中的位运算不但可以取出各种值,而且我们可以对他对数据进行排序
举例如下,新闻列表中的一个字段标识为
1:置顶
2:不置顶
4:推荐
8:不推荐
该字段的值可以为这4种状态的组合,如果我们根据一定条件想把所有置顶的放在前面该如何做呢
select * from t_News order by iFlag & 1 desc
这样我们就把所有置顶的贴子排在前面,当然这里可以加上一定的Where 条件,在Where 里也可可以加一定的位运算,
关于位运算可以查阅相应的SQL 帮助
下面来讲一讲C#中的枚举位运算
这里我们定义一个枚举
[Flags]
enum UserFlag
{
a = 1,
b = 2,
c = 4,
d = 8,
e = 16,
f = 32
}
在代码里加上如下处理
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string strSQL = "select * from v_User where iFlag & @iFlag = @iFlag";
//SqlParameter parm = new SqlParameter("@iFlag",SqlDbType.Int,4);
//parm.Value = UserFlag.a | UserFlag.b ;
SqlConnection con = new SqlConnection("server=.;database=Sinvan_TexDB;User Id=sa;pwd=123;");
SqlCommand comm = new SqlCommand(strSQL, con);
comm.Parameters.Add("@iFlag", SqlDbType.Int, 4).Value = UserFlag.a | UserFlag.b;
SqlDataAdapter adp = new SqlDataAdapter(comm);
DataTable dTable = new DataTable();
adp.Fill(dTable);
UserFlag userFlag = (UserFlag)Enum.Parse(typeof(UserFlag), dTable.Rows[0][11].ToString());
}
}
进行处理之后userFlag就是数据库中存在的各种组合
我们同样可对其进行一定的位运算处理
如我们想加上 UserFlag.c 可进行如下操作
userFlag = userFlag | Userflag.c
如想去掉UserFlag.c 可进行如下操作
userFlag = userFlag ^ UserFlag.c
如我们要判断是该标识中是否存在c可进行如下操作
(userFlag & UserFlag.c) == UserFlag.c