基本上,我有一个报告列表,每个报告都属于一个区域。每个用户在每个区域都有权限。我需要列出用户可以看到的报告,即属于登录用户具有常规读取权限的区域的报告。
我正在使用linq表达式创建一个谓词并运行dettachedQuert。
我已经在这个问题上工作了一段时间,发现了很多建议,例如:-LinqKit -https://www.tabsoverspaces.com/233644-playing-with-parameters-limit-on-sql-server-with-entity-framework -Entity Framework Hitting 2100 Parameter Limit
由于我没有完全检索列表,我只是在运行一个谓词,所以似乎不是我的情况。
使用“ contains”可以解决2100个参数,因为我的数据库中有3000多个区域。我首先要做的是将区域分为两个列表,第一个包含我允许的区域,第二个包含不允许的区域。最小的清单是我的谓词。这种方法可以工作一段时间,但是现在我有4500多个区域。因此,这不再起作用。
var predicate = PredicateBuilder.Create<Report>();
var areasWithPermission = user.Permissions.Where(v => v.Access != AccessType.NotAllowed).Select(v => v.Area.Id).ToList();
var areasWithoutPermission= user.Permissions.Where(v => v.Access == AccessType.NotAllowed).Select(v => v.Area.Id).ToList();
var predicateSearchPermissions = PredicateBuilder.Create<Report>();
if (areasWithPermission > areasWithoutPermission){
predicateSearchPermissions = predicateSearchPermissions.OrElse(a => !areasWithoutPermission.Contains(a.Area.Id))
}else{
predicateSearchPermissions = predicateSearchPermissions.OrElse(a => areasWithPermission .Contains(a.Area.Id))
}
predicate = predicate.AndAlso(predicateSearchPermissions);
答案 0 :(得分:0)
请勿将权限带入内存以仅将其发送出去。而是“联接”查询中的表。 像这样:
var reports = from r in reports
let areasWithPermission = user.Permissions.Where(v => v.Access != AccessType.NotAllowed).Select(v => v.Area.Id)
let areasWithoutPermission = user.Permissions.Where(v => v.Access == AccessType.NotAllowed).Select(v => v.Area.Id)
where areasWithPermission.Any(id => id == r.Area.Id) ||
!areasWithoutPermission.Any(id => id == r.Area.Id)
select r;