假设我们有两个表(在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)
到目前为止一直很好,但我有两个问题要问:
更新:可以让事情变得更加复杂让我们假设我们想让前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
我能做对吗?这个查询必须这么复杂吗?有没有更简单的方法呢?
答案 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();