[英]How to exclude from query's result in linq?
在第一張圖片中,我有第一個查詢的結果,突出顯示的部分表示將通過在第二個查詢上應用過濾器來排除的行,在第二張圖片中,我有查詢select * from exlusion_table
的結果
我必須對第一個查詢進行更改以使其排除從第二個查詢中檢索到的項目
第一個查詢:
var u = from a in cx.VW_LIST
where (a.PRJ == codPrj) && (a.DATE > date_ || a.DATE == null || date_ == null)
&& (x.Contains(a.CODE) || x.Count() == 0)
select a)
第二個查詢:
var y = from esc in cx.EXCLUSION select esc
應修改第一個查詢以排除所有具有值 fcode = 第二個查詢的 fcode(在第二個查詢的 fscode = null 的情況下)或那個(fcode = 第二個查詢的 fcode && fscode = 第二個查詢的 fscode )
你可以使用任何()。 IE:
var u = from a in cx.VW_LIST
where (a.PRJ == codPrj)
&& (a.DATE > date_ || a.DATE == null || date_ == null)
&& (x.Contains(a.CODE) || x.Count() == 0)
&& (!cx.EXCLUSION.Any( y => x.fscode == y.fscode && x.fcode == y.fcode ))
select a)
有兩種方法,一種是使用!
和ANY()
過濾掉在其他列表中找到的記錄,這將編譯成WHERE NOT EXISTS(_exclusion_)
過濾表達式
var excluded = cx.EXCLUSION.AsQueryable();
var query = from vw in cx.VW_LIST
where vw.PRJ == codPrj
where vw.DATE == null || date_ == null || vw.DATE > date_
where !x.Any() || x.Contains(vw.CODE)
where !excluded.Any(esc => vw.fcode == esc.fcode
&& (esc.fscode == null || vw.fscode == esc.fscode))
select vw;
var results = query.ToList();
棘手的元素是排除表中null
的fscode
,它需要充當通配符匹配,或者否定fscode
比較。
沒有必要將excluded
的查詢拆分成它自己的查詢,我們可以直接引用cx.EXCLUSION
表,它會產生完全相同的效果,這向您展示了一種用於構建 LINQ 查詢的封裝技術您可以輕松地增加排除查找的復雜性,而不會造成整個查詢的混亂。
您可能還會發現需要有條件地構建查詢,這就是 Fluent syntax 提供更模塊化方法的地方:
bool filterExcludedRecords = true;
...
var excluded = cx.EXCLUSION.AsQueryable();
var query = cx.VW_LIST.Where(vw => vw.PRJ == codPrj)
.Where(vw => vw.DATE == null || date_ == null || vw.DATE > date_)
.Where(vw => !x.Any() || x.Contains(vw.CODE));
if(filterExcludedRecords)
query = query.Where(vw => !excluded.Any(esc => vw.fcode == esc.fcode
&& (esc.fscode == null || vw.fscode == esc.fscode)));
var results = query.ToList();
另一種方法是在未找到排除匹配項的情況下使用LFET OUTER JOIN
:
var excluded = cx.EXCLUSION.AsQueryable();
var query = from vw in cx.VW_LIST
where vw.PRJ == codPrj
where vw.DATE == null || date_ == null || vw.DATE > date_
where !x.Any() || x.Contains(vw.CODE)
from esc in excluded.Where(e => vw.fcode == e.fcode
&& (e.fscode == null || vw.fscode == e.fscode))
.DefaultIfEmpty()
where esc.fscode == null
select vw;
var results = query.ToList();
WHERE NOT EXISTS
通常在性能方面更勝一籌, OUTER JOIN
在未優化的表中或當排除列表中的行數非常少而主表中的行數非常大時,可能會提供更好的響應。
我包括這個查詢選項是為了完整性,眾所周知,您可以通過向查詢添加新from
子句來創建簡單的外部聯接。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.