将两个返回bool值的LINQ查询合并为一个返回bool值的LINQ查询

本文关键字:值的 LINQ 查询 返回 bool 一个 两个 合并 | 更新日期: 2023-09-27 18:08:46

我在一个返回bool?的方法中有以下两个LINQ查询(目标EF 6.1):

if (db.Permissions.Any(p => p.Key == permission && p.Roles.Any(r => !r.IsAllowed 
                                && r.Role.Users.Any(u => u.UserId == userId))))
{
    return false;
}
if (db.Permissions.Any(p => p.Key == permission && p.Roles.Any(r => r.IsAllowed 
                                && r.Role.Users.Any(u => u.UserId == userId))))
{
    return true;
}
return null;

第一个检查用户是否在!IsAllowed的任何角色中,如果是,则返回false(=>用户/角色被拒绝权限,这将推翻任何"允许")。然后,它检查用户是否处于设置了IsAllowed的任何角色中,并在这种情况下返回true。如果没有为用户的任何角色设置权限,则返回null
由于!IsAllowed通常不是用户,因此在大多数情况下会导致对DB的两次查询。

是否有一种方法可以对直接返回bool?的DB使用一个查询?

将两个返回bool值的LINQ查询合并为一个返回bool值的LINQ查询

您应该能够按IsAllowed订购,然后选择第一个。这应该把false s放在第一位,然后是true s。未经测试,但我认为你已经明白了:

return db.Permissions.Where(p => p.Key == permission)
    .SelectMany(p => p.Roles.Where(r => r.Role.Users.Any(u => u.UserId == userId))
                            .Select(r => r.IsAllowed))
    .OrderBy(a => a)
    .Select(a => (bool?)a)
    .FirstOrDefault();

可能有更优雅的解决方案,但您可以连接表并按IsAllowed排序以获得第一条(如果有的话)记录。

bool? allowed = (from p in db.Permissions
join r in db.Roles on p.id equals r.Permission_id
join u in db.Users on r.id equals u.Role_id
where p.Key == permission && u.UserId == userId
orderby r.IsAllowed
select r.IsAllowed
).FirstOrDefault();
return allowed;
编辑:哎呀,有人抢在我前面了。基本上是一样的