[英]Conditionally allowing for null in LINQ WHERE clause
我試圖在我的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 ... )))
我想改編以上內容來介紹'后備'檢查; 沒有按預期工作。
Contact
Permission
(即p==null
)時,則僅包括基於allowed
的預定bool
值的行。 我以為我可以where (p==null && 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 ... )))
即使是true
總是輸出,如果allowed=false
?
WHERE
((t1.PermissionId IS NOT NULL AND ... other conditions ... ))
我希望我只是做一些很容易修復的傻事。
如何根據給定的bool
值過濾我的null
值記錄?
您正在此處執行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
再次展平分組,因此對於allowed == true
的情況,仍然需要.DefaultIfEmpty()
。
我懷疑我正在使用的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 ...))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.