在职的:

我正在尝试在我的 Contacts 表和我的 Permissions 表之间执行 LEFT OUTER JOIN。我有这个正常工作的基础,无论他们是否有相应的权限,都会得到一个联系人列表。

// Query for Contacts
from contact in Contacts
join permission in Permissions on contact.Id equals permission.ObjectId into permissionGrp
from p in permissionGrp.DefaultIfEmpty()
where p==null || (p!=null && /* ... condition based on the existence of a permission */)
select new { contact, permission = p };

生成 WHERE SQL:
WHERE
(t1.PermissionId IS NULL OR
    ((t1.PermissionId IS NOT NULL AND ... other conditions ... )))

问题:

我想修改上述内容以引入“回退”检查;没有按预期工作。

要求:
  • 当没有与 Permission (即 Contact )对应的 p==null 时,仅包含基于 bool 的预定 allowed 值的行。

  • 试图:

    我以为我可以像这样做 where (p==null && allowed) || ...:

    // Fallback permission
    bool allowed = false;
    
    // Query for Contacts
    from contact in Contacts
    join permission in Permissions on contact.Id equals permission.ObjectId into permissionGrp
    from p in permissionGrp.DefaultIfEmpty()
    
    /* Added bool condition 'allowed' to control inclusion when 'p' is null */
    where (p==null && allowed) || (p!=null && /* ... condition based on the existence of a permission */)
    select new { contact, permission = p };
    

    预期的:

    allowed = false (不接受 null 权限)
    WHERE
        ((t1.PermissionId IS NOT NULL AND ... other conditions ... ))
    

    allowed = true(接受 null 权限)
    WHERE
    (t1.PermissionId IS NULL OR
        ((t1.PermissionId IS NOT NULL AND ... other conditions ... )))
    

    实际结果:

    即使是 allowed=false ,也总是像 true 一样输出?
    WHERE
        ((t1.PermissionId IS NOT NULL AND ... other conditions ... ))
    

    概括:

    我希望我只是在做一些很容易解决的傻事。
    如何根据给定的 null 值过滤我的 bool 值记录?

    最佳答案

    您正在此处执行 GroupJoin。所以第一部分的结果 permissionGrp 是一个匿名类型 IGrouping<Permission> 。这已经是 OUTER JOIN 的等价物。

    您可以通过有条件地测试 IGrouping<Permission> 是否包含元素来实现您想要的:

    from contact in Contacts
    join permission in Permissions on contact.Id equals permission.ObjectId
        into permissionGrp
    where allowed || g.Any()
    from p in permissionGrp.DefaultIfEmpty()
    select new { contact, permission = p };
    

    请注意, from p in permissionGrp 再次使分组变平,因此对于 .DefaultIfEmpty() 的情况仍然需要 allowed == true

    关于c# - 在 LINQ WHERE 子句中有条件地允许 null,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20175266/

    10-16 06:43
    查看更多