如何编写高效Linq语句关联查询报表与权限表实现按公司权限过滤?
Linq实现多权限规则报表查询方案
前置实体定义
首先确认你已定义和表映射的实体类:
Report对应REPORT主表:- 字段:
int Id、string ReportName、int IsRestricted(0代表非受限,1代表受限)
- 字段:
Access对应ACCESS权限表:- 字段:
int Id、string Company、string ReportName
- 字段:
最高效查询写法(数据库IQueryable场景,适配EF/EF Core)
优先用Any()做存在性判断,EF会自动生成EXISTS子查询,性能远高于关联JOIN,尤其数据量较大时优势更明显:
// 传入的当前访问公司 var currentCompany = "google"; var accessibleReports = dbContext.Reports .Where(r => // 非受限报表全部可见 r.IsRestricted == 0 // 受限报表需要匹配当前公司的权限记录 || dbContext.Accesses.Any(a => a.Company == currentCompany && a.ReportName == r.ReportName) ) .ToList();
样例验证
当currentCompany = "google"时,查询返回结果完全匹配需求:
- 报表a:
IsRestricted=0,直接返回 - 报表b:
IsRestricted=1,ACCESS表存在google对应报表b的权限,返回 - 报表c:
IsRestricted=1,无对应权限,不返回
内存集合场景优化写法
如果是操作内存中的IEnumerable集合,可以提前将当前公司的权限转成哈希表,把判断复杂度降到O(1):
// 提前提取当前公司的所有可访问受限报表,转哈希集合优化查询速度 var permittedReportSet = accessList .Where(a => a.Company == currentCompany) .Select(a => a.ReportName) .ToHashSet(); var accessibleReports = reportList .Where(r => r.IsRestricted == 0 || permittedReportSet.Contains(r.ReportName)) .ToList();
性能优化建议
如果是数据库查询,建议在ACCESS表的Company和ReportName字段建立联合索引,可进一步提升子查询的执行效率。
内容的提问来源于stack exchange,提问作者Taylor
相关产品推荐
相关产品推荐

