使用linq创建超过2100个参数的searchPredicate时,是否有解决方法?

时间:2019-07-16 19:27:08

标签: c# .net entity-framework linq

基本上,我有一个报告列表,每个报告都属于一个区域。每个用户在每个区域都有权限。我需要列出用户可以看到的报告,即属于登录用户具有常规读取权限的区域的报告。

我正在使用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);

这是我的环境的简单表示 enter image description here

1 个答案:

答案 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;