我有一个对象列表List<Parent> Parents
。
Parent
类有一个List<Child> Children
。
到目前为止,我已经使用LINQ:
对Parents
应用了分页 List<Parent> PageX = Parents.Skip(PageIndex * PageSize).Take(PageSize);
例如,如果PageSize=2,结果如下:
--------------- 第1页 ----------------------
父1儿童1 儿童2 孩子
3
父2儿童1 儿童2
--------------- 第二页 ----------------------
父母3
儿童1 父4儿童1 儿童2
我想达到的目标如下:
--------------- 第1页 ----------------------
父1儿童1 儿童2
--------------- 第二页 ----------------------
孩子3
父2儿童1
--------------- 第3页 ----------------------
儿童2 父母3
儿童1
我怎样才能做到这一点?
您可以使用SelectMany
:
var page = parents.SelectMany(p => p.Children)
.Skip(PageIndex * PageSize).Take(PageSize);
在这里看到一个工作的小提琴。
更新:
我做了一些研究,因为这也让我感兴趣。使用以下假设:
- 您正在使用EF
- 你只有一个层次的父->子关系
- 你的实体都有一个
Position
属性
您应该能够对DB执行以下操作,以"在一个查询中"以正确的顺序获取页面的项:
var pageItems = db.Parents.SelectMany(p => p.Children).Include(c => c.Parent)
.OrderBy(c => c.Parent.Position).ThenBy(c => c.Position)
.Skip(PageIndex * PageSize).Take(PageSize);
我没有测试这个代码,因为我没有DB在这里测试它,所以请报告回来,如果你可以测试它,如果假设是正确的为您的情况。
我假设Parent
和Child
都具有用于识别它们的共同属性(例如Name
) ?
在这种情况下,您必须将层次结构扁平化,以便在同一列表级别包含父级和子级信息。
假设如下:
class Parent
{
public string Name { get; set; }
private readonly List<Child> _children = new List<Child>();
public List<Child> Children
{
get { return _children; }
}
}
class Child
{
public string Name { get; set; }
}
您可以使用:
将其平展为单个IEnumerable<string>
var flattened = Parents
.Select(p => new [] { p.Name }.Concat(p.Children.Select(c => c.Name)))
.SelectMany(x => x);
然后按之前的方式分页:
var results = flattened.Skip(PageIndex * PageSize).Take(PageSize);
foreach (var x in results)
Console.WriteLine(x);
Parent
和Child
都继承自同一个类或接口,可能会更酷。