4.21:
简单RBAC项目获取用户所在权限的菜单项
第一款方案:用户表、用户角色表、角色表、角色权限表、权限表五表联查
public List<PermissionDto> GetMenus(long userid)
{
//获取全部的数据
var user = _dbContext.Users.AsQueryable();
var role = _dbContext.Roles.AsQueryable();
var user_role = _dbContext.User_Roles.AsQueryable();
var perm = _dbContext.Permissions.AsQueryable();
var role_perm = _dbContext.Role_Permissions.AsQueryable();
var roleModel = from a in user
join b in user_role on a.Id equals b.UserId
join c in role on b.RuleId equals c.Id
join d in role_perm on c.Id.ToString() equals d.RoleId
join e in perm on d.PermId equals e.Id
where (a.Id == userid)
select new PermissionDto() {
PermissionId = e.Id,
PermName = e.PermName,
PermUrl = e.PermUrl,
ParentId = e.ParentId,
Children = null
};
//根据一级菜单的父ID获取一级菜单的所有数据
var list = roleModel.Where(x => x.ParentId == "M").ToList();
//然后获取二级菜单的数据
foreach (var item in list)
{
var query =roleModel.Where(x => x.ParentId == item.PermissionId);
item.Children = query.ToList();
}
return list;
}
后面经过思考,发现用户表和角色表实际不需要,简化为3个表
var roleList = (
from b in user_role
join d in role_perm
on b.RuleId.ToString() equals d.RoleId
join e in perm
on d.PermId equals e.Id
where (b.UserId == userid)
select e).ToList();
但是之前的方案都是固定的,只有2级菜单可以如此实现,但是如果菜单层级更多呢?
通过递归方式获取:
通过list和父级ID,获取每一级的数据,然后将当前层级的权限ID作为下一层级的父级ID,通过递归的思想,调用自身一级一级的获取下一级数据,这样菜单层级再多也能搞定。
public List<PermissionDto> GetMenus(List<Permission> list,string pId)
{
//准备返回数据
List<PermissionDto> dtoList = new List<PermissionDto>();
//获取第一级的数据
var result = list.Where(x => x.ParentId == pId);
foreach (var item in result) //通过循环将数据转化为需要的格式DTO
{
PermissionDto dto = new PermissionDto();
dto.PermissionId = item.Id;
dto.ParentId = item.ParentId;
dto.PermName = item.PermName;
dto.PermUrl = item.PermUrl;
dto.Children = GetMenus(list, item.Id); //通过递归的方式获取下一级菜单数据
dtoList.Add(dto);
}
return dtoList;
}
再改进了下,通过select映射的方式
public List<PermissionDto> GetMenus(List<Permission> list,string pId)
{
#region select方式
var dtoList = list.Where(x => x.ParentId == pId).Select(x => new PermissionDto()
{
PermissionId = x.Id,
PermName = x.PermName,
PermUrl = x.PermUrl,
ParentId = x.ParentId,
Children = GetMenus(list, x.Id)
}).ToList();
return dtoList;
#endregion
}
总结:多表连接查询按照实际需要的表进行查询
递归方式实现菜单项
Select映射方式替换foreach循环方式
.Net Core内置中间件初识:
今天初步了解了下.net core中间件的知识,当用户的一个Request访问到API时,按照如下的顺序执行中间件
ExceptionHandler:异常中间件
HSTS:(HTTP Strict Transport Security),作用是强制客户端(如浏览器)使用HTTPS与服务器创建连接
HttpsRedirection:重定向中间件
Static Files:静态文件中间件
Routing:路由中间件
CORS:跨域中间件
Authentication:鉴权中间件
Authorization:授权中间件
Custom middlewares:自定义中间件