2010-08-03 43 views
1

我想构建我的linq-to-sql表达式,以便它只生成单个SQL数据库查询。该查询涉及两个嵌套选择,一个简化版本是:构建嵌套的linq-to-sql表达式以生成单个SQL查询

var query = from person in People 
      where person.ID == 1234 
      select new PersonDetails() 
      { 
       ID = person.ID, 
       FirstName = person.FirstName, 
       LastName = person.LastName, 
       Addresses = from address in Addresses 
          where address.PersonID == person.ID 
          select address 
       PhoneNumbers = from number in PhoneNumbers 
           where number.PersonID == person.ID 
           select number 
      } 

该表达式将导致两个SQL查询被执行。第一个加入Person和PhoneNumbers表,并从它们中提取所需的信息。第二个查询是来自Addresses表的简单选择。如果我注释掉电话号码属性,那么只有一个连接人员和地址的查询会被执行,因此L2S引擎确实可以识别这两个关系。

有没有人有任何想法我可以如何构建LINQ表达式,以便linq-to-sql只会生成一个单一的SQL查询?

回答

1
     (from person in Persons 
         join address in Addresses 
         on person.id equals address.personid 
         join phone in PhoneNumbers 
         on person.id equals phone.personid 
         select new 
         { 
          Person = person, 
          Address = address, 
          Phone = phone 
         }) 
         .GroupBy(p => p.Person.id) 
         .Select(g => new 
         { 
          Person = g.FirstOrDefault().Person, 
          Addresses = g.Select(k=>k.Address).Distinct(), 
          PhoneNumbers = g.Select(k=>k.Phone).Distinct() 
         }); 
+0

这似乎是混合查询表达式与扩展方法。有没有什么方法可以用查询表达式来实现呢? – Jacques 2017-02-14 13:06:56

1

您可以使用 “让” 的文章:

from person in context.Persons 
. 
. 
let Add = from address in Addresses 
          where address.PersonID == person.ID 
          select address 

这确实一个子查询。

+0

看起来L2S在let语句周围有一些智慧。如果我在我的linq表达式中使用两个let语句,它仍然以两个单独的SQL查询结束,其中第一个使用左外连接来处理let。 – sipwiz 2010-08-04 00:56:00