[英]Linq to Entities, Inject Join Inside Query Expression
我正在嘗試提高某些LINQ查詢的性能,有一件小事情需要大量改進:聯接。 幾乎我所有的查詢都有一些用於過濾結果的聯接,但未選擇到結果中。 這些過濾條件是可選的...
我今天所擁有的是:
var q = from t1 in context.Set<T1>()
where t1.mandatoryfilter >= 0
select t1;
if (useFilter)
{
var q2 = from t1 in q
from t2 in context.Set<T2>().Where(t2 => t2.fk == t1.pk).DefaultIfEmpty
where t2.filterProperty == filterValue
select t1;
if (useFilter2)
{
[...]
return q3.ToList();
}
return q2.ToList();
}
else
{
if (useFilter2)
{
[...]
return q2.ToList();
}
return q.ToList();
}
這將生成查詢的投影。 並且根據過濾器的復雜性/數量,它會生成越來越多的投影,並且如果我需要組合一些過濾器,則需要嵌套代碼。 結果查詢的大小可能會變得很大,以致無法通過Internet發送(實際上不是太大的XD,但它會導致性能問題),並且代碼本身也很難維護。
我知道我可以改回字符串SQL ...但這不是一個非常優雅的解決方案嗎?
我想知道是否有一種方法可以注入聯接,而過濾器直接執行表達式樹,因此提供程序將不會生成投影,並且代碼將是線性且簡單的。
ps:非常重要的信息,我使用的是EF6,Linq-to-Entities,默認SqlClient。
謝謝大家。
我對LINQ的查詢語法版本不太有把握,並且沒有打開VS,因此我使用方法語法來確保我正確無誤:但是同樣的想法適用。
這是應用過濾器的相當標准的方法。 您不必每次都創建新查詢,只需為每個過濾器附加一個謂詞即可。 也適用於聯接(除非您使用自定義聯接,否則可能無需顯式使用.Join
)
var people = context.Set<Person>()
.Where(p => p.mandatoryFilter > 0);
if (filter.WithAddress != null)
people = people.Where(p => p.Address == filter.WithAddress);
if (filter.WithBossName != null)
people = people.Where(p => p.Boss.Name == filter.WithBossName);
return people.ToList();
如果使用導航屬性,則幾乎不需要連接,並且可以將大多數過濾條件作為單個表達式應用。
假設您的T1
實體具有導航屬性T2
。 過濾器表達式將如下所示:
q = q.Where(q.T2.filterProperty1 == filterProperty == filterValue);
您還可以在此處看到僅將表達式追加到現有查詢q
。
現在,它變成一種常用的模式,以向IQueryable
添加過濾條件:
IQueryable<T1> query = from t1 in context.Set<T1>()
where t1.mandatoryfilter >= 0
select t1;
if (filterValue2 != null)
query = query.Where(t => t.T2.filterProperty == filterValue2);
if (filterValue3 != null)
query = query.Where(t => t.T3.filterProperty == filterValue3);
if (filterValue4 != null)
query = query.Where(t => t.T4.filterProperty == filterValue4);
(請注意, query
應IQueryable
為IQueryable
,否則分配query = query....
請勿編譯。)
現在,您甚至可以將過濾器應用於1:n關聯
if (filterValue5 != null)
query = query.Where(t => t.T5s.Any(t5 => t5.filterProperty == filterValue5));
如果使用join
進行過濾,則無法執行此操作,因為它將使結果集相乘。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.