使用LINQ的对象分页列表



我有一个对象列表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在这里测试它,所以请报告回来,如果你可以测试它,如果假设是正确的为您的情况。

我假设ParentChild都具有用于识别它们的共同属性(例如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);
如果您的ParentChild都继承自同一个类或接口,可能会更酷。

最新更新