[英]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.