注册 登录
编程论坛 ASP.NET技术论坛

如何将角色与任务的关系写进数据库中?

foshan 发布于 2007-07-30 09:31, 2846 次点击
我参考了别人的界面,是为不同的角色设置不同的访问权的,下图中,左边为角色列表,右边为执行的操作。如果 CheckBox 打上勾就表示该角色拥有勾选的操作的权限。
一、如何实现将角色与任务的关系写进数据库中?
例如,我在界面左边的GridView控件上选定了“系统管理员”,然后在右边的GridView控件上勾选了上面的三个选项,然后按“更新”按钮,在“更新”按钮的click事件中如何用代码将“系统管理员”的ID与选定任务的ID写进数据库中?
二、如何实现在该页面中,选择了某一角色后,右边的GridView控件根据数据表中该角色的任务极限在相应的CheckBox 打上勾?

只有本站会员才能查看附件,请 登录

[此贴子已经被作者于2007-7-30 9:38:17编辑过]

25 回复
#2
foshan2007-07-30 09:34

前台代码如下:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Role-Task.aspx.cs" Inherits="Admin_User_Role_Task_Role_Task" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>角色配置</title>
<style type="text/css">
.hidden
{display:none;}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</div>
<div style="z-index: 101; left: 19px; width: 232px; position: absolute; top: 5px;
height: 242px">
<asp:Label ID="Label1" runat="server" Text="角色列表"></asp:Label><br />
<asp:Panel ID="Panel2" runat="server" Height="500px" BorderColor="PeachPuff" BorderStyle="Double" ScrollBars="Auto">
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" BackColor="#DEBA84"
BorderColor="#DEBA84" BorderStyle="None" BorderWidth="1px" CellPadding="3" CellSpacing="2"
EmptyDataText="数据不存在……" Font-Size="Smaller" GridLines="None" OnRowCancelingEdit="GridView1_RowCancelingEdit"
OnRowCreated="GridView1_RowCreated" OnRowDeleting="GridView1_RowDeleting"
OnRowEditing="GridView1_RowEditing" OnRowUpdating="GridView1_RowUpdating" OnSelectedIndexChanged="GridView1_SelectedIndexChanged" Width="250px">
<FooterStyle BackColor="#F7DFB5" ForeColor="#8C4510" />
<Columns>
<asp:BoundField DataField="RoleId" HeaderText="ID" ReadOnly="True">
<ItemStyle CssClass="hidden" Width="0px" />
<HeaderStyle CssClass="hidden" Width="0px" />
</asp:BoundField>
<asp:TemplateField HeaderText="角色名称">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("RoleName") %>' TextMode="MultiLine"
Width="168px"></asp:TextBox>
</EditItemTemplate>
<ItemStyle Width="180px" />
<HeaderStyle BackColor="#FFFFC0" ForeColor="Black" />
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("RoleName", "{0}") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True" CommandName="Update"
Text="更新"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False" CommandName="Cancel"
Text="取消"></asp:LinkButton>
<ajaxToolkit:ConfirmButtonExtender ID="ConfirmButtonExtender1" runat="server" ConfirmText="确要取消当前操作?"
TargetControlID="LinkButton2">
</ajaxToolkit:ConfirmButtonExtender>
</EditItemTemplate>
<ItemStyle HorizontalAlign="Center" Width="40px" />
<HeaderStyle Width="40px" />
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False" CommandName="Edit"
Text="编辑"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False" CommandName="Delete"
Text="删除"></asp:LinkButton>
<ajaxToolkit:ConfirmButtonExtender ID="ConfirmButtonExtender2" runat="server" ConfirmText="确要删除数据?"
TargetControlID="LinkButton2">
</ajaxToolkit:ConfirmButtonExtender>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowSelectButton="True" />
</Columns>
<RowStyle BackColor="#E3EAEB" ForeColor="#8C4510" Wrap="False" />
<SelectedRowStyle BackColor="#738A9C" Font-Bold="True" ForeColor="Blue" />
<PagerStyle ForeColor="#8C4510" HorizontalAlign="Center" />
<HeaderStyle BackColor="#A55129" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="OldLace" BorderStyle="None" />
</asp:GridView>
&nbsp;&nbsp;&nbsp;
<br />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</asp:Panel>
<table cellpadding="2" cellspacing="1">
<tr>
<td style="width: 3px">
<asp:TextBox ID="TextBox2" runat="server" Width="168px"></asp:TextBox></td>
<td style="width: 3px">
<asp:Button ID="Button1" runat="server" Text="添加角色" OnClick="Button1_Click" /></td>
</tr>
</table>
</div>
<div style="z-index: 102; left: 324px; width: 100px; position: absolute; top: 5px;
height: 100px">
<asp:Label ID="Label2" runat="server" Text="允许执行的任务列表" Width="200px"></asp:Label><br />
<asp:Panel ID="Panel1" runat="server" Height="500px" ScrollBars="Auto" BorderColor="PeachPuff" BorderStyle="Double">
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False" BackColor="#DEBA84"
BorderColor="#DEBA84" BorderStyle="None" BorderWidth="1px" CellPadding="3" CellSpacing="2"
EmptyDataText="数据不存在……" Font-Size="Smaller" GridLines="None"
OnRowCreated="GridView1_RowCreated" Width="250px">
<FooterStyle BackColor="#F7DFB5" ForeColor="#8C4510" />
<Columns>
<asp:BoundField DataField="GongNengMiaoShu_Id" HeaderText="ID" ReadOnly="True">
<ItemStyle CssClass="hidden" Width="0px" />
<HeaderStyle CssClass="hidden" Width="0px" />
</asp:BoundField>
<asp:TemplateField HeaderText="允许">
<EditItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</EditItemTemplate>
<ItemStyle HorizontalAlign="Center" Width="30px" />
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="GongNengMiaoShu" HeaderText="功能描述" />
</Columns>
<RowStyle BackColor="#E3EAEB" ForeColor="#8C4510" Wrap="False" />
<SelectedRowStyle BackColor="#738A9C" Font-Bold="True" ForeColor="Blue" />
<PagerStyle ForeColor="#8C4510" HorizontalAlign="Center" />
<HeaderStyle BackColor="#A55129" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="OldLace" BorderStyle="None" />
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button2" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</asp:Panel>
<asp:Button ID="Button2" runat="server" Text="更新" /></div>
</form>
</body>
</html>

#3
foshan2007-07-30 09:41

后台部分代码:

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
SqlConnection conn = new SqlConnection("data source=(local);database=****;user=****; password=****");
DataSet ds = new DataSet();
SqlDataAdapter da1 = new SqlDataAdapter("select * from roles", conn);
da1.Fill(ds, "roles");
SqlDataAdapter da2 = new SqlDataAdapter("select * from Authority", conn);
da2.Fill(ds, "Authority");
GridView1.DataSource = ds;
GridView1.DataMember = "roles";
GridView1.DataBind();
GridView2.DataSource = ds;
GridView2.DataMember = "Authority";
GridView2.DataBind();
}
}

#4
foshan2007-07-30 09:49
数据表如下图所示:

只有本站会员才能查看附件,请 登录

#5
cyyu_ryh2007-07-30 10:27
首先你的表设计有问题,没主键
你点击编辑时弹出任务表,同时把roleid传入任务列表中,再根据第三张表显示是否打沟
注意:你第三张表主要存储的是某个角色对应的不同任务
这需要两个查询,同时查询后面两张表,根据关系显示
#6
foshan2007-07-30 10:40
谢谢斑竹!不太明白……
大家有否这方面的代码供小弟参考?
RoleId 和 TaskId 分别为角色表和任务表的主键……
#7
冰彩虹2007-07-30 11:12
一、如何实现将角色与任务的关系写进数据库中?
例如,我在界面左边的GridView控件上选定了“系统管理员”,然后在右边的GridView控件上勾选了上面的三个选项,然后按“更新”按钮,在“更新”按钮的click事件中如何用代码将“系统管理员”的ID与选定任务的ID写进数据库中?
(更新时,先删除角色和任务关系表该角色下的所有记录,然后插入你选中的关系数据)

二、如何实现在该页面中,选择了某一角色后,右边的GridView控件根据数据表中该角色的任务极限在相应的CheckBox 打上勾?
(这个就需要你查出角色下拥有的权限数据后,遍历右边的GridView与查询出来的数据进行匹配,满足的就把相应行的CheckBox打勾)

不知道这样说得清楚不?
#8
cyyu_ryh2007-07-30 11:50
楼上的不错,基本上是这个意思
#9
foshan2007-07-30 12:49

谢谢两位斑竹的热心教导,还有问题请教:

问题一:
斑竹的第一点意思是:在角色与任务关系表中,将某个角色的所拥有的所有任务权限放在一起,用逗号隔分(一个角色对应一个任务数组)还是在数据表一个角色ID对应一个任务ID?
例如:

ID RoleId TaskId
1 1 1,2,4,6
2 2 3,5,7

还是

ID RoleId TaskId
1 1 1
2 1 2
3 1 4
4 1 6
5 2 3
6 2 5
7 2 7

问题二
以上不管采用哪一种方式存放权限,当查出角色下拥有的权限数据后,如何实现遍历右边的GridView与查询出来的数据进行匹配,满足的就把相应行的CheckBox打勾?

#10
冰彩虹2007-07-30 19:07
问题一:
两种存放数据方式都可以,不过第一种取数据需要额外的做些分离的操作,个人推荐使用第二种方式,看你第三张表就很适合这种多对多的关系数据

问题二:
假设查出角色下拥有的权限放在一个list里面,然后类似下面的
foreach(GridViewRow row in GridView2)
{
if(list.Contains(row.Cells[1].Text))
{
CheckBox checkBox = (CheckBox)row.FindControl("CheckBox1");
checkBox.Checked = true;
}
}

PS:家里电脑没有vs,在记事本里随便写的,可能有些笔误
#11
foshan2007-07-31 11:09

谢谢斑竹!
问题一 中如果使用第二种方式,在“更新权限”时需将数据库中该角色的所有数据行删除,然后再重新添加该角色与所有任务的关系。以下的代码实现了将权限重新写入数据表,不知是否还有更加好的方法。
CheckBox chk;
foreach (GridViewRow r in GridView2.Rows)
{
chk = (CheckBox)r.FindControl("Checkbox1");
if (chk != null)
{
if (chk.Checked)
{
DataRow addrow = ds1.Tables[0].NewRow();
//addrow[1] = Session["JsId"].ToString();
addrow["RoleId"] = GridView1.SelectedRow.Cells[0].Text.Trim();
addrow["GongNeng_Id"] = r.Cells[0].Text.Trim();
ds1.Tables[0].Rows.Add(addrow);
da1.Update(ds1, "relRoleAndAuthority");
}
}
}
问题二 ,如何将从数据库筛选出来的数据放在 ArrayList 中?以下代码不会怎样写了(红色部分),请帮忙,谢谢!
SqlConnection conn = new SqlConnection("data source=(local);database=****;user=****; password=****");
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter("select GongNeng_Id from relRoleAndAuthority where RoleId = " + GridView1.SelectedRow.Cells[0].Text, conn);
da.Fill(ds, "Authority");
ArrayList MyList = new ArrayList();
MyList = ds.Tables["Authority"].Rows;
????
foreach (GridViewRow row in GridView2.Rows)
{
if (MyList.Contains(row.Cells[1].Text))
{
CheckBox checkBox = (CheckBox)row.FindControl("CheckBox1");
checkBox.Checked = true;
}
}

[此贴子已经被作者于2007-7-31 11:10:47编辑过]

#12
冰彩虹2007-07-31 11:16
红色部分
IList<String> MyList = new List<String>();
foreach (DataRow row in ds.Tables["Authority"].Rows)
{
if (!list.Contains(row[1].ToString()))
list.Add(row[1].ToString());
}
#13
foshan2007-07-31 11:28
谢谢斑竹!
IList<String> MyList = new List<String>();
foreach (DataRow row in ds.Tables["Authority"].Rows)
{
if (!MyList.Contains(row[1].ToString()))
MyList.Add(row[1].ToString());
}
运用后,遇到两个错误提示,请问应如何解决,谢谢!
错误 1 非泛型 类型“System.Collections.IList”不能与类型参数一起使用
错误 2 找不到类型或命名空间名称“List”(是否缺少 using 指令或程序集引用?)
#14
冰彩虹2007-07-31 11:32
添加System.Collections.Generic引用
#15
foshan2007-07-31 11:49

谢谢!还有一个问题:如何一次性将GridView中所有的CheckBox均处于非选定状态?以下是笨办法:
foreach (GridViewRow row in GridView2.Rows)
{
CheckBox checkBox = (CheckBox)row.FindControl("CheckBox1");
checkBox.Checked = false;
if (MyList.Contains(row.Cells[0].Text))
{
checkBox.Checked = true;
}
}

[此贴子已经被作者于2007-7-31 11:52:20编辑过]

#16
冰彩虹2007-07-31 11:54
<HeaderTemplate>
<input id="chkAll" onclick="javascript:SelectAllCheckboxes(this);" runat="server" type="checkbox" title="全选" />
</HeaderTemplate>

function SelectAllCheckboxes(spanChk){
 var oItem = spanChk.children;
 var theBox=(spanChk.type=="checkbox")?spanChk:spanChk.children.item[0];
 xState=theBox.checked;
 elm=theBox.form.elements;
 for(i=0;i<elm.length;i++)
 if(elm[i].type=="checkbox" && elm[i].id!=theBox.id)
 {
  if(elm[i].checked!=xState)
  elm[i].click();
 }
}
#17
sean882007-07-31 15:02
以下是引用foshan在2007-7-31 11:49:30的发言:

谢谢!还有一个问题:如何一次性将GridView中所有的CheckBox均处于非选定状态?以下是笨办法:
foreach (GridViewRow row in GridView2.Rows)
{
CheckBox checkBox = (CheckBox)row.FindControl("CheckBox1");
checkBox.Checked = false;
if (MyList.Contains(row.Cells[0].Text))
{
checkBox.Checked = true;
}
}


你可以在前台设置模板列的checkBox的Checked 状态为False,然后台循环里根据MyList需要改变checkBox的Checked 状态,如:

前台:
<asp:TemplateColumn HeaderText="checkbox">
<ItemTemplate>
<FONT face="宋体">
<asp:CheckBox id="CheckBox1" runat="server" Checked="False"></asp:CheckBox></FONT>
</ItemTemplate>
</asp:TemplateColumn>

后台:
foreach (GridViewRow row in GridView2.Rows)
{
CheckBox checkBox = (CheckBox)row.FindControl("CheckBox1");
if (MyList.Contains(row.Cells[0].Text))
{
checkBox.Checked = true;
}
}

#18
foshan2007-08-02 08:47
以下是引用冰彩虹在2007-7-31 11:32:34的发言:
添加System.Collections.Generic引用

谢谢!问题解决了。

#19
foshan2007-08-02 08:58
以下是引用cyyu_ryh在2007-7-30 10:27:44的发言:
首先你的表设计有问题,没主键
谢谢斑竹!昨天晚上专门研究了这方面的知识,终于知道这是多对多的关系,现将关系图呈上,请斑竹看看是否正确?
我还有一个问题不明白:我看有关的示例,发现数据表的主键字段的数据类型是uniqueidentifier,而我现在的主键字段数据类型是int、标识设置为“是”、标识种子设置为“1”、标识递增量设置为“1”。
不知我现在的这种主键的设置与示例中主键的设置对比,有何不妥当的地方?如果数据表的主键字段的数据类型是uniqueidentifier,在将数据写入该数据表时,该字段的内容是否是数据库像“标识种子”一样自动进行填充的?
只有本站会员才能查看附件,请 登录

[此贴子已经被作者于2007-8-2 12:43:51编辑过]

#20
cyyu_ryh2007-08-02 12:56

第一张设计错误
主键ID
其他为负键
由其他两张关联
你点击日roles列又键有个主外键关联在里面设置关联

#21
foshan2007-08-02 16:49

谢谢斑竹!不过,我看书说什么ASP.NET2.0如果安装了SQL2005,会在APP_Data文件有个aspnet_M***的数据库,里面就是设置了 联合主键的……不知是否是书在有误,我没有装SQL2005,不能实地看到书中所说的是真的。不知斑竹有何意见……

#22
cyyu_ryh2007-08-02 17:56
2005我只是连接过服务器
具体没用过
#23
爱像深蓝2007-08-02 22:47

回复楼主在下认为你的基本的业务逻辑有点问题.
在下看来有3张表是正确的
角色表
role_id pk
role_name

任务表
task_id pk
task_name

关系表
task_id pk,fk
role_id pk,fk

这里的关系表的引用的两张表的外键.又同时约束对方表的主键,故同为主外键关系

例:
角色编号 角色名
01 张三
02 李四
任务编号 任务名称
01 修改密码
02 导出excel
10 备份数据库

它们的关系
角色编号 任务编号
01 01
01 02
02 01
02 10
这个表说的关系就是
张三有密码修改和导出excel文件的任务
李四也有密码修改但第二个任务是备份数据库

张三一人的多种权限时,这时任务编号就为主键
而当李四和张三同时拥有密码修改时,这时的角色编号就成为参照的主键.
当然在类图里是可以有包含关系的.即一个单元格里多个数据.即一个单元格可以包含一个集合
而在数据库里是范式的限定是否容许出现.一个单元格里包含多条信息的.

角色编号 任务编号
01 01,02
这样的一个单元格里有01,02两个编号是不容许出现的哟.

#24
foshan2007-08-03 08:09
谢谢上楼朋友--爱像深蓝 的详尽分析,不好意思我还不太明白你所说我的在第19楼的关系图显示的数据表的“基本的业务逻辑有点问题”的问题所在。

我还有一个问题不明白:我看有关的示例,发现数据表的主键字段的数据类型是uniqueidentifier,而我现在的主键字段数据类型是int、标识设置为“是”、标识种子设置为“1”、标识递增量设置为“1”。
不知我现在的这种主键的设置与示例中主键的设置对比,有何不妥当的地方?如果数据表的主键字段的数据类型是uniqueidentifier,在将数据写入该数据表时,该字段的内容是否是数据库像“标识种子”一样自动进行填充的?
#25
zd1234562007-08-03 11:11
#26
foshan2007-08-06 08:20
爱像深蓝 能否解答我在第24楼的问题?谢谢!
1