2008-09-18 99 views
5

谈到作为一个非C#精明的程序员,我很好奇,LINQ查询的评价语义如下所示:LINQ-to-SQL支持可组合查询吗?

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查询以生成内存结构,然后将查询​​查询?或者​​的构建只是从people中提取有关查询的数据,然后产生一个新的数据库对等查询?所以,如果我迭代了这两个查询,将执行多少个SQL语句?

回答

12

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

由于LINQ查询懒洋洋地评估(例如不再执行,直到你遍历元素),你的代码表明将不实际接触数据库。直到你迭代其他人或人会SQL生成和执行。

1

people和​​包含IQueryable<Person>类型的对象。

如果您遍历两者separatly,它将运行两个查询。 如果您只遍历​​,它将运行预期的查询,并带有两个where子句。

如果您在people上做.ToList()并在第二个查询中使用返回的List<Person>而不是人员,它将变成LINQ-to-Objects并且不执行SQL。

这种行为被称为延迟执行。意思是在需要之前没有查询完成。在执行之前,它们只是表达式树,被操纵来制定最终查询。

0

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

3

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

的LINQ做到这一点通过表达式树。第一个linq语句生成一个表达式树;它不执行查询。第二个linq语句建立在第一个创建的表达式树上。该语句仅在枚举生成的集合时执行。

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获得通过为发送“丹尼尔“

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为 “丹尼尔”

如有疑问,请致电您的IQueryable的toString()方法或者给一个TextWriter到DataContext的Log属性。