C#Linq-如何管理父子查询的分页?

时间:2015-03-08 10:36:26

标签: c# sql linq

假设我们有两个表(在SQL Server中),如下所示:

Parent
Child

并且每个父母可以有零个或多个孩子 我们想加载10个第一父母和他们的孩子。(显然我们不能使用TOP 10因为它返回TOP 10记录而不是TOP 10父母)

我们可以写这个SQL语句

 SELECT * 
 FROM 
     (SELECT TOP 10 * FROM Parent ORDER BY Id) AS parents 
 LEFT JOIN 
     Child AS children ON parents.Id = children.ParentID 
 --(and we can add a where clause if we want to filter the result)

到目前为止一直很好,但我有两个问题要问:

  1. 我们如何使用Linq(使用方法)编写相同的查询
  2. 我们如何跳过,例如10个父母,以及其他10个父母(当然还有他们的孩子)?
  3. 更新:可以让事情变得更加复杂让我们假设我们想让前10名父母认为他们的孩子符合给定的标准,例如他们的名字就像乔一样我们拥有:

    SELECT * 
    FROM 
        (SELECT TOP 10 * 
         FROM 
             (SELECT DISTINCT p.* 
              FROM Parent p 
              INNER JOIN Child c ON p.Id = c.ParentId 
                AND c.Name like '%Joe%') AS p1 ORDER BY Id) AS Parents  
    LEFT JOIN 
        Child AS children ON parents.Id = children.ParentID
    

    我能做对吗?这个查询必须这么复杂吗?有没有更简单的方法呢?

1 个答案:

答案 0 :(得分:2)

您可以在LINQ查询语法中借助 Linq Join 运算符加入这两个表。 但在此之前使用Take()表的Parent扩展方法:

var res = (from p in context.Parent.Take(10)  // Take 10 elements
              join c in context.Child on p.ID equals c.ParentID into g
                   from result in g.DefaultIfEmpty()  // Left join
              select new { Parent = p, Child = c}).ToList();

如果您想获得下一个 n 元素,可以在Skip()之前使用Take()。此外,在获取某些 n 元素之前,您可能需要对Parent进行排序。然后就是这样:

...context.Parent.OrderBy(x => x.ID).Skip(10).Take(10)...

有关您的更新:

你可以试试这个:

var firstPart = (from p in context.Parent  // Take 10 elements
              join c in context.Child on p.ID equals c.ParentID
              where c.Name.Contains("Joe")
              select p).Distinct().Take(10);

var secondPart = from p in firstPart
                 join c in context.Child on p.ID equals c.ParentID into g
                       from result in g.DefaultIfEmpty()  // Left join
                  select new { Parent = p, Child = c}).ToList();