基本上,我有一个报告列表,每个报告都属于一个区域。每个用户都有每个区域的权限。我需要列出我的用户可以看到的报告,即属于登录用户至少具有读取权限的区域的报告。
我正在使用linq表达式创建一个谓词并通过detachedQuery运行。
我已经在这个问题上工作了一段时间,找到了很多建议,比如:- LinqKit - https://www.tabsoverspaces.com/233644-playing-with-parameters-limit-on-sql-server-with-entity-framework - Entity Framework Hitting 2100 Parameter Limit
似乎没有我的情况,因为我不是确切地检索列表,我只是运行一个谓词。
由于我的数据库中有超过3000个区域,所以使用“包含”解决了2100个参数的问题。我首先尝试做的是在两个列表中划分区域,第一个包括我有权限的区域,第二个包括不允许的区域。最小的列表是我的谓词。这种方法在一段时间内工作得很好,但现在我有超过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);下面是我的环境的一个简单表示:

发布于 2019-07-17 19:42:45
不要仅仅为了将权限发送到内存中而将它们放入内存。相反,“连接”查询中的表。类似于:
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;https://stackoverflow.com/questions/57064203
复制相似问题