LINQ-to-SQL是否支持可组合查询?

时间:2008-09-18 01:28:06

标签: sql linq linq-to-sql code-reuse

作为一名非C#精明的程序员,我很好奇LINQ查询的评估语义,如下所示:

var people = from p in Person
             where p.age < 18
             select p

var otherPeople = from p in people
                  where p.firstName equals "Daniel"
                  select p

假设Person是定义agefirstName字段的ADO实体,从数据库的角度来看,这会做什么?具体来说,是否运行people查询以生成内存结构,然后由otherPeople查询查询?或者otherPeople的构造是否仅仅从people提取有关查询的数据,然后生成新的数据库对等查询?那么,如果我迭代这两个查询,那么将执行多少个SQL语句?

5 个答案:

答案 0 :(得分:12)

它们是可组合的。这是可能的,因为LINQ查询实际上是表达式(代码作为数据),LINQ提供程序(如LINQ-to-SQL)可以评估并生成相应的SQL。

因为LINQ查询被懒惰地评估(例如,在迭代元素之前不会执行),所以您显示的代码实际上不会触及数据库。直到你遍历其他人或者人们才会生成并执行SQL。

答案 1 :(得分:3)

是的,结果查询是由组成的。它包括完整的where子句。打开SQL分析并尝试自己查看。

Linq通过表达式树来做到这一点。第一个linq语句生成一个表达式树;它不执行查询。第二个linq语句建立在第一个创建的表达式树上。只有在枚举结果集合时才会执行该语句。

答案 2 :(得分:3)

var people = from p in Person
             where p.age < 18
             select p

转换为:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0]
WHERE [t0].[Age] < @p0

其中@ p0通过18

发送
var otherPeople = from p in people
                  where p.firstName equals "Daniel"
                  select p

转换为:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0]
WHERE [t0].[FirstName] = @p0

其中@ p0作为“Daniel”

发送
var morePeople = from p1 in people
                 from p2 in otherPeople
                 where p1.PersonId == p2.PersonId
                 select p1;

转换为:

SELECT [t0].[PersonId], [t0].[Age], [t0].[FirstName]
FROM [dbo].[Person] AS [t0], [dbo].[Person] AS [t1]
WHERE ([t0].[PersonId] = [t1].[PersonId]) AND ([t0].[Age] < @p0) AND ([t1].[FirstName] = @p1)

其中@ p0是18,@ p1是“Daniel”

如有疑问,请调用IQueryable上的ToString()或将TextWriter提供给DataContext的Log属性。

答案 3 :(得分:1)

peopleotherPeople包含IQueryable<Person>类型的对象。

如果你分别迭代它们,它会运行两个查询。 如果只迭代otherPeople,它将运行预期的查询,并带有两个where子句。

如果您在.ToList()上执行people并在第二个查询中使用返回的List<Person>而不是人,则它将成为LINQ到对象,并且不会执行任何SQL。

此行为称为延迟执行。意味着在需要之前不会进行任何查询。在执行之前,它们只是被操纵以形成最终查询的表达式树。

答案 4 :(得分:0)

当您尝试访问最终结果时,这两个查询都将执行。您可以尝试查看从DataContext对象属性生成的原始SQL。