I am trying to perform a LEFT OUTER JOIN between my Contacts table and my Permissions table. I have the basis of this working correctly, and get back a list of contacts regardless of whether they have a corresponding permission.
// 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 };
Generated WHERE SQL:
WHERE
(t1.PermissionId IS NULL OR
((t1.PermissionId IS NOT NULL AND ... other conditions ... )))
I want to adapt the above to introduce 'fallback' check; Not working as expected.
Permission corresponding to the Contact (i.e. p==null) then only include the row based on the predetermined bool value of allowed.I thought I could do where (p==null && allowed) || ... like this:
// 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 (don't accept null permission)WHERE
((t1.PermissionId IS NOT NULL AND ... other conditions ... ))
allowed = true (accept null permission)WHERE
(t1.PermissionId IS NULL OR
((t1.PermissionId IS NOT NULL AND ... other conditions ... )))
Always outputs as if allowed=false even when true?
WHERE
((t1.PermissionId IS NOT NULL AND ... other conditions ... ))
I hope I am just doing something silly that's easily fixed.
How can I filter my null value records based on a given bool value?
You are performing a GroupJoin here. So the result of the first part, permissionGrp, is an anonymous type IGrouping<Permission>. This already is the eqivalent of an OUTER JOIN.
You can achieve what you want by conditionally testing whether or not the IGrouping<Permission> contains elements:
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 };
Note that from p in permissionGrp flattens the grouping again, so .DefaultIfEmpty() is still necessary for the case where allowed == true.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With