[英]Sorting Multiple Levels of Child Collections with LINQ to Entities
考慮以下模型:
public class Form
{
public Guid Id
{
get;
set;
}
public List<Section> Sections
{
get;
set;
}
}
public class Section
{
public Guid Id
{
get;
set;
}
public List<Question> Questions
{
get;
set;
}
public int SortOrder
{
get;
set;
}
}
public class Question
{
public Guid Id
{
get;
set;
}
public int SortOrder
{
get;
set;
}
}
當我使用LINQ to Entities檢索一個或多個Form
對象時,我希望通過SortOrder
屬性對Section
對象的關聯集合進行排序。 此外,在每個這些Section
對象中,我想以相同的方式對相關的Question
對象集合進行排序。
我不記得我在哪里讀它,但是我已經能夠使用類似於以下內容的LINQ查詢來使第一級排序工作:
var query =
from
f in context.Form
where
f.Id == *some form id*
select
new
{
Root = f,
Sections = f.Sections.OrderBy(s => s.SortOrder)
};
從那里,我可以使用類似的方法來獲取實際的Form
對象:
var form = query.ToList().Select(q => q.Root).FirstOrDefault();
我無法弄清楚的是如何編寫LINQ查詢以將此行為擴展到第二級集合(每個Section
對象中的Question
對象的集合)。
*更新*
請參閱下面我對Ivan的評論,該評論解釋了此問題不是重復的。
要實現您所需要的,可以使用Eager Loading :
var query= from f in context.Form.Include(f=>f.Sections.Select(s=>s.Questions))
where f.Id == *some form id*
select
new
{
Root = f,
Sections = f.Sections
.OrderBy(s => s.SortOrder)
.Select(s=> new{s.Id, s.SortOrder, Questions=s.Questions.OrderBy(q=>q.SortOrder)})
};
Include
擴展方法使您甚至可以將與查詢相關的實體包括在內,甚至包括更深層次的內容(請查看我在上面引用的鏈接中的“ 備注”部分)。
第二種解決方案可能是使用延遲加載 ,如果您尚未禁用此功能(默認情況下處於啟用狀態),則需要滿足一些要使用的要求 ,例如,導航屬性必須為virtual
。
您也可以像@IvanStoev引用的帖子中的解決方案一樣對內存中的導航屬性進行排序,但是,如果要將相關實體按某種順序進行過濾,過濾以及其他操作,則可以考慮使用Explicit Loading :
foreach f in context.Form
{
context.Entry(f).Collection(r => r.Sections)
.Query().OrderBy(s=>s.SortOrder)
.Load();
}
但是恕我直言,最好的解決方案是創建自定義類(也稱為DTO )以投影所需的結果,僅在一次往返中加載所需的數據
考慮到您直接查詢整個表集,那么就不需要使用.Include()
方法來進行.Include()
Eager Loading
。
這是通過顯式映射屬性/列來解決此問題的lambda表示方式。
// TODO: replace the null value with a real context DbSet<Form>
IQueryable<Form> forms = null;
var form = forms.Select(x => new Form()
{
Id = x.Id,
Sections = x.Sections.OrderBy(s => s.SortOrder).Select(s => new Section()
{
Id = s.Id,
SortOrder = s.SortOrder,
Questions = s.Questions.OrderBy(q => q.SortOrder).Select(q => new Question()
{
Id = q.Id,
SortOrder = q.SortOrder
}).ToList()
}).ToList()
}).FirstOrDefault();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.