获取父菜单的所有子详细信息
Get All The Child Details of Parent Menu
我正在开发一个菜单访问权限系统,管理员可以在其中将用户分配到包含菜单访问权限的组。单独授予用户权限很简单。但是对于组许可,我几乎没有匹配的标准。所以这里是表格结构和示例数据:
----USER DETAILS----
CREATE TABLE HRD.USER_DETAILS
(
EMPNO VARCHAR2(20 BYTE),
ENAME VARCHAR2(40 BYTE),
ENTRY_DATE DATE,
STATUS INT
);
EMP-0001 John 6/10/2018 1
EMP-0002 Jack 5/12/2018 1
----GROUP DETAILS----
CREATE TABLE HRD.GROUP_DETAILS
(
GROUPNO VARCHAR2(20 BYTE),
GROUPNAME VARCHAR2(40 BYTE),
DETAILS VARCHAR2(100 BYTE),
ENTRY_DATE DATE,
STATUS INT
);
GROUP-0001 GROUP-1 1/1/2018 1
GROUP-0002 GROUP-2 1/1/2018 1
----MENU DETAILS----
CREATE TABLE HRD.MENU_DETAILS
(
MENUNO VARCHAR2(20 BYTE),
MENUNAME VARCHAR2(40 BYTE),
DETAILS VARCHAR2(100 BYTE),
PARENT VARCHAR2(10 BYTE),
ENTRY_DATE DATE,
STATUS INT
);
1001 User Details 0 1/1/2018 1
1002 Add User 1001 1/1/2018 1
1003 Department Details 0 1/1/2018 1
1004 Add Department 1003 1/1/2018 1
----ASSIGN MENU DETAILS----
CREATE TABLE HRD.ASSIGN_MENU_DETAILS
(
GROUPNO VARCHAR2(20 BYTE),
MENUNO VARCHAR2(20 BYTE),
DETAILS VARCHAR2(100 BYTE),
ENTRY_DATE DATE,
STATUS INT
);
GROUP-0001 1001 1/1/2018 1
GROUP-0001 1004 1/1/2018 1
----USER GROUP DETAILS----
CREATE TABLE HRD.USER_GROUP_DETAILS
(
EMPNO VARCHAR2(20 BYTE),
GROUPNO VARCHAR2(20 BYTE),
DETAILS VARCHAR2(100 BYTE),
ENTRY_DATE DATE,
STATUS INT
);
EMP-0001 GROUP-0001 1/1/2018 1
EMP-0001 GROUP-0002 1/1/2018 1
所以使用下面的查询,我得到以下信息:
SELECT M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME FROM USER_GROUP_DETAILS m INNER JOIN ASSIGN_MENU_DETAILS k ON K.GROUPNO = M.GROUPNO
LEFT JOIN (SELECT P.MENUNO, P.MENUNAME FROM MENU_DETAILS p WHERE P.PARENT = '0' OR P.PARENT <> '0') q ON Q.MENUNO = K.MENUNO
GROUP BY M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME;
EMP-0001 GROUP-0001 1001 User Details
EMP-0001 GROUP-0001 1004 Add Department
由于用户没有 GROUP-0002 的菜单权限,因此查询时不应该显示任何菜单。这里是最重要的事情: GROUP-0001 有两个菜单权限 1) 用户详细信息 2) 添加部门
用户详情菜单是父菜单,添加部门是部门详情菜单的子菜单。所以我期望的是,只要分配了子菜单,那么父菜单也应该在查询中可见。现在 Add Department 菜单有父级 Department Details,因此也必须反映父级。
我不确定我是否会使用查询或 C#
来完成它,但也尝试使用 C#
代码,但似乎逻辑构建不完美。
C#:
foreach (var parent in GetViewModel())
{
foreach (var child in GetViewModel2(parent.Parent))
{
sampleDynamicNav = new List<NavBarItem> {
new NavBarItem {
D = 1, Text = parent.MenuName, Icon = new ItemIcon {Default = HRMS_New_VS2.Properties.Resources.nav_new_home, Hover = HRMS_New_VS2.Properties.Resources.nav_new_home, Selected = HRMS_New_VS2.Properties.Resources.nav_new_home}, ToolTip = "tooltip Main Menu", Height = 40,
Childs = new List<NavBarItem> {
new NavBarItem {ID = child.MenuNo, Text = child.MenuName, Height = 30 },
}
}
};
}
}
public IEnumerable<EmpViewModel> GetParent()
{
List<EmpViewModel> lstEmp = new List<EmpViewModel>();
string query = "SELECT M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME, Q.PARENT FROM USER_GROUP_DETAILS m INNER JOIN ASSIGN_MENU_DETAILS k ON K.GROUPNO = M.GROUPNO " +
"LEFT JOIN (SELECT P.MENUNO, P.MENUNAME, P.PARENT FROM MENU_DETAILS p) q ON Q.MENUNO = K.MENUNO WHERE M.EMPNO = 'EMP-0001' " +
"GROUP BY M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME, Q.PARENT";
DataTable dt = SelectData(query);
if (dt != null && dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
EmpViewModel bo = new EmpViewModel();
bo.Parent = dr["PARENT"].ToString();
bo.MenuName = dr["MENUNAME"].ToString();
bo.MenuNo = Convert.ToInt32(dr["MENUNO"].ToString());
lstEmp.Add(bo);
}
}
return lstEmp;
}
public IEnumerable<EmpViewModel> GetChild(string menuNo)
{
List<EmpViewModel> lstEmp = new List<EmpViewModel>();
string query = "SELECT M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME, Q.PARENT FROM USER_GROUP_DETAILS m INNER JOIN ASSIGN_MENU_DETAILS k ON K.GROUPNO = M.GROUPNO " +
"LEFT JOIN (SELECT P.MENUNO, P.MENUNAME, P.PARENT FROM MENU_DETAILS p) q ON Q.MENUNO = K.MENUNO WHERE M.EMPNO = 'EMP-0001' AND Q.PARENT = '" + menuNo + "'" +
"GROUP BY M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME, Q.PARENT";
DataTable dt = SelectData(query);
if (dt != null && dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
EmpViewModel bo = new EmpViewModel();
bo.Parent = dr["PARENT"].ToString();
bo.MenuName = dr["MENUNAME"].ToString();
bo.MenuNo = Convert.ToInt32(dr["MENUNO"].ToString());
lstEmp.Add(bo);
}
}
return lstEmp;
}
预期输出 - 对于菜单权限:GROUP-0001 用户
Menu - 01: User Details
Menu - 02: Department Details
-> Add Department
N.B:一个用户可以分配到多个组,组可以重复两次菜单权限。在这种情况下,它应该反映不同的菜单,使父菜单和子菜单保持相邻。暂时搁置一边。
您可以使用递归 CTE 获取所有父菜单。
WITH
CTE (MENUNO,
MENUNAME,
PARENT) AS
(
SELECT M.MENUNO,
M.MENUNAME,
M.PARENT
FROM USER_DETAILS U
INNER JOIN USER_GROUP_DETAILS UG
ON UG.EMPNO = U.EMPNO
INNER JOIN ASSIGN_MENU_DETAILS AM
ON AM.GROUPNO = UG.GROUPNO
INNER JOIN MENU_DETAILS M
ON M.MENUNO = AM.MENUNO
WHERE U.EMPNO = 'EMP-0001'
UNION ALL
SELECT M.MENUNO,
M.MENUNAME,
M.PARENT
FROM MENU_DETAILS M
INNER JOIN CTE C
ON C.PARENT = M.MENUNO
)
SELECT DISTINCT
MENUNO,
MENUNAME
FROM CTE;
我正在开发一个菜单访问权限系统,管理员可以在其中将用户分配到包含菜单访问权限的组。单独授予用户权限很简单。但是对于组许可,我几乎没有匹配的标准。所以这里是表格结构和示例数据:
----USER DETAILS----
CREATE TABLE HRD.USER_DETAILS
(
EMPNO VARCHAR2(20 BYTE),
ENAME VARCHAR2(40 BYTE),
ENTRY_DATE DATE,
STATUS INT
);
EMP-0001 John 6/10/2018 1
EMP-0002 Jack 5/12/2018 1
----GROUP DETAILS----
CREATE TABLE HRD.GROUP_DETAILS
(
GROUPNO VARCHAR2(20 BYTE),
GROUPNAME VARCHAR2(40 BYTE),
DETAILS VARCHAR2(100 BYTE),
ENTRY_DATE DATE,
STATUS INT
);
GROUP-0001 GROUP-1 1/1/2018 1
GROUP-0002 GROUP-2 1/1/2018 1
----MENU DETAILS----
CREATE TABLE HRD.MENU_DETAILS
(
MENUNO VARCHAR2(20 BYTE),
MENUNAME VARCHAR2(40 BYTE),
DETAILS VARCHAR2(100 BYTE),
PARENT VARCHAR2(10 BYTE),
ENTRY_DATE DATE,
STATUS INT
);
1001 User Details 0 1/1/2018 1
1002 Add User 1001 1/1/2018 1
1003 Department Details 0 1/1/2018 1
1004 Add Department 1003 1/1/2018 1
----ASSIGN MENU DETAILS----
CREATE TABLE HRD.ASSIGN_MENU_DETAILS
(
GROUPNO VARCHAR2(20 BYTE),
MENUNO VARCHAR2(20 BYTE),
DETAILS VARCHAR2(100 BYTE),
ENTRY_DATE DATE,
STATUS INT
);
GROUP-0001 1001 1/1/2018 1
GROUP-0001 1004 1/1/2018 1
----USER GROUP DETAILS----
CREATE TABLE HRD.USER_GROUP_DETAILS
(
EMPNO VARCHAR2(20 BYTE),
GROUPNO VARCHAR2(20 BYTE),
DETAILS VARCHAR2(100 BYTE),
ENTRY_DATE DATE,
STATUS INT
);
EMP-0001 GROUP-0001 1/1/2018 1
EMP-0001 GROUP-0002 1/1/2018 1
所以使用下面的查询,我得到以下信息:
SELECT M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME FROM USER_GROUP_DETAILS m INNER JOIN ASSIGN_MENU_DETAILS k ON K.GROUPNO = M.GROUPNO
LEFT JOIN (SELECT P.MENUNO, P.MENUNAME FROM MENU_DETAILS p WHERE P.PARENT = '0' OR P.PARENT <> '0') q ON Q.MENUNO = K.MENUNO
GROUP BY M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME;
EMP-0001 GROUP-0001 1001 User Details
EMP-0001 GROUP-0001 1004 Add Department
由于用户没有 GROUP-0002 的菜单权限,因此查询时不应该显示任何菜单。这里是最重要的事情: GROUP-0001 有两个菜单权限 1) 用户详细信息 2) 添加部门
用户详情菜单是父菜单,添加部门是部门详情菜单的子菜单。所以我期望的是,只要分配了子菜单,那么父菜单也应该在查询中可见。现在 Add Department 菜单有父级 Department Details,因此也必须反映父级。
我不确定我是否会使用查询或 C#
来完成它,但也尝试使用 C#
代码,但似乎逻辑构建不完美。
C#:
foreach (var parent in GetViewModel())
{
foreach (var child in GetViewModel2(parent.Parent))
{
sampleDynamicNav = new List<NavBarItem> {
new NavBarItem {
D = 1, Text = parent.MenuName, Icon = new ItemIcon {Default = HRMS_New_VS2.Properties.Resources.nav_new_home, Hover = HRMS_New_VS2.Properties.Resources.nav_new_home, Selected = HRMS_New_VS2.Properties.Resources.nav_new_home}, ToolTip = "tooltip Main Menu", Height = 40,
Childs = new List<NavBarItem> {
new NavBarItem {ID = child.MenuNo, Text = child.MenuName, Height = 30 },
}
}
};
}
}
public IEnumerable<EmpViewModel> GetParent()
{
List<EmpViewModel> lstEmp = new List<EmpViewModel>();
string query = "SELECT M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME, Q.PARENT FROM USER_GROUP_DETAILS m INNER JOIN ASSIGN_MENU_DETAILS k ON K.GROUPNO = M.GROUPNO " +
"LEFT JOIN (SELECT P.MENUNO, P.MENUNAME, P.PARENT FROM MENU_DETAILS p) q ON Q.MENUNO = K.MENUNO WHERE M.EMPNO = 'EMP-0001' " +
"GROUP BY M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME, Q.PARENT";
DataTable dt = SelectData(query);
if (dt != null && dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
EmpViewModel bo = new EmpViewModel();
bo.Parent = dr["PARENT"].ToString();
bo.MenuName = dr["MENUNAME"].ToString();
bo.MenuNo = Convert.ToInt32(dr["MENUNO"].ToString());
lstEmp.Add(bo);
}
}
return lstEmp;
}
public IEnumerable<EmpViewModel> GetChild(string menuNo)
{
List<EmpViewModel> lstEmp = new List<EmpViewModel>();
string query = "SELECT M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME, Q.PARENT FROM USER_GROUP_DETAILS m INNER JOIN ASSIGN_MENU_DETAILS k ON K.GROUPNO = M.GROUPNO " +
"LEFT JOIN (SELECT P.MENUNO, P.MENUNAME, P.PARENT FROM MENU_DETAILS p) q ON Q.MENUNO = K.MENUNO WHERE M.EMPNO = 'EMP-0001' AND Q.PARENT = '" + menuNo + "'" +
"GROUP BY M.EMPNO, M.GROUPNO, K.MENUNO, Q.MENUNAME, Q.PARENT";
DataTable dt = SelectData(query);
if (dt != null && dt.Rows.Count > 0)
{
foreach (DataRow dr in dt.Rows)
{
EmpViewModel bo = new EmpViewModel();
bo.Parent = dr["PARENT"].ToString();
bo.MenuName = dr["MENUNAME"].ToString();
bo.MenuNo = Convert.ToInt32(dr["MENUNO"].ToString());
lstEmp.Add(bo);
}
}
return lstEmp;
}
预期输出 - 对于菜单权限:GROUP-0001 用户
Menu - 01: User Details
Menu - 02: Department Details
-> Add Department
N.B:一个用户可以分配到多个组,组可以重复两次菜单权限。在这种情况下,它应该反映不同的菜单,使父菜单和子菜单保持相邻。暂时搁置一边。
您可以使用递归 CTE 获取所有父菜单。
WITH
CTE (MENUNO,
MENUNAME,
PARENT) AS
(
SELECT M.MENUNO,
M.MENUNAME,
M.PARENT
FROM USER_DETAILS U
INNER JOIN USER_GROUP_DETAILS UG
ON UG.EMPNO = U.EMPNO
INNER JOIN ASSIGN_MENU_DETAILS AM
ON AM.GROUPNO = UG.GROUPNO
INNER JOIN MENU_DETAILS M
ON M.MENUNO = AM.MENUNO
WHERE U.EMPNO = 'EMP-0001'
UNION ALL
SELECT M.MENUNO,
M.MENUNAME,
M.PARENT
FROM MENU_DETAILS M
INNER JOIN CTE C
ON C.PARENT = M.MENUNO
)
SELECT DISTINCT
MENUNO,
MENUNAME
FROM CTE;