我正在尝试在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
值记录?
答案 0 :(得分:1)
您在此处执行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
。
答案 1 :(得分:1)
我怀疑我正在使用的ORM(LightSpeed)中存在一个错误,我会引起他们的注意。
我找到了一个合适的工作,使用let
子句。
// 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()
/* Work around for 'allowed' not being honoured properly, using 'let' */
let isAllowed = allowed
/* Added bool condition 'isAllowed' to control inclusion when 'p' is null */
where (p==null && isAllowed) || (p!=null && /* ... condition based on the existence of a permission */)
select new { contact, permission = p };
现在使用已知值与其自身的比较作为布尔检查。在这种情况下t0.ContactId
。
allowed=true
... t0.ContactId = t0.ContactId
WHERE
((t1.PermissionId IS NULL AND t0.ContactId = t0.ContactId) OR
(t1.PermissionId IS NOT NULL AND ... other conditions ...))
allowed=false
... t0.ContactId <> t0.ContactId
WHERE
((t1.PermissionId IS NULL AND t0.ContactId <> t0.ContactId) OR
(t1.PermissionId IS NOT NULL AND ... other conditions ...))