[英]Entity Framework include Where
如果我有一個如下所示的查詢:
var forms = repo.GetForms().Where(f => f.SubForms.Any(sf => sf.Classes.Any(c => c.TermId == termId)));
從這里你可以看到我的架構如下:
SubForm
有許多具有多個Term
Class
。
我想要的是:
所有SubForms
及其在特定Term
的Classes
。
現在發生的事情是我獲得了在特定Term
中具有任何Class
所有SubForm
。 這意味着SubForm
會返回所有子Class
,而不僅僅是與Term
相關的子Class
。
例如。 我有2個術語,每個術語有2個類的子表單。 此查詢返回4個類而不是該特定術語中的2個類。
是否有任何Include('Expression')
可以用來表示我只想根據條件包含所有類? 或者我的查詢錯了?
用這個:
var subForms = repo.GetSubForms.Select(sf = new {
SubForm = sf,
Classes = sf.Classes.Where(c => c.TermId == termId)
}).ToList()
.Select(t => t.SubForm)
.ToList();
更新:根據@ Slauma的評論:
如果要加載SubForm
s表示他們有任何Class
,有一個Term
由termId
,你可以從去年底開始, 像這樣:
var subForms = repo.Terms.Where(t => t.Id == termId).Select(t => new {
Term = t,
Class = t.Class,
SubForm = t.Class.SubForm
}).ToList()
.Select(t => t.SubForm).ToList();
或者以最簡單的方式,您可以在您的Term
上使用Include
,請參閱:
var subForms = repo.Terms.Include("Class.SubForm").Where(t => t.Id == termId)
.Select(t => t.Class.SubForm).ToList();
注意:正如我從您的問題中可以理解的那樣,您有這樣的關系:
SubForm has_many Class has_many Term
但是,您提供的代碼顯示的是這樣的關系:
SubForm has_many Class
Term has_many Class
如果可以的話,請提出您的實體,或者更多地解釋他們之間的關系。 謝謝。
Include(Where Expression)
不存在。 如果您使用Include進行預先加載,您將始終加載所有元素。
通過使用投影可以解決這個問題。 基本思想是,您將選擇具有所需屬性的新匿名類型,以及具有已過濾導航項的另一個屬性。 EF將這些鏈接在一起,因此你會偽造一個Include(Where ... )
請查看此示例 。
你知道有時候我開始迷失在花哨的LINQ擴展方法中,並試圖弄清楚如何急切地加載我想要的東西,並采用一個非常簡單的“連接”概念。
var result =
(from f in SubForums
from c in Classes
from t in Term
where t.TermId = 1
select new { SubForum = f, Class = c, Term = t }).ToList();
這是一個使用預定義導航屬性的簡單連接(因此您不必指定連接條件)。 您將返回一個匿名類型,其中包含您需要的所有內容。 這樣做的好處在於Entity Framework會為您進行自動修復,因此,如果您願意,您可以自由地從您的方法返回SubForum,它將自動包含Class和后續Term引用。
我不知道這些關系的確切名稱,但它應該是符合的
repo.Terms
.Include("Classes")
.Include("Classes.SubForms")
.SingleOrDefault(x => x.TermId = termId);
// or
repo.GetSubForms
.Include("Classes")
.Where(sf => sf.Classes.Where(c => c.TermId == termId));
這似乎是一個普遍的要求,當我今年早些時候看時,很難找到解決方案。 我最終使用了下面鏈接中包含的解決方案(我不確定這是我找到的確切解決方案,但它是相同的想法)。 希望這可以幫助!
//Found this method to filter our child objects instead of using .include()
var Results = (from res in
(from u in DataContext.User
where u.Type.ToUpper() != "ADMIN"
&& u.StartDate <= DateTime.Now
&& (u.EndDate == null || u.EndDate >= DateTime.Now)
select new
{
User = u,
Access = u.Access.Where(a => a.StartDate <= DateTime.Now
&& (a.EndDate == null || a.EndDate >= DateTime.Now))
}
)
select res);
//The ToArray is neccesary otherwise the Access is not populated in the Users
ReturnValue = Results.ToArray().Select(x => x.User).ToList();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.