Linq to sql 有没有办法重写这个LINQ查询,使它只执行一个SQL查询?

Linq to sql 有没有办法重写这个LINQ查询,使它只执行一个SQL查询?,linq-to-sql,optimization,Linq To Sql,Optimization,我有一个LINQ查询,它获取嵌套对象的列表 from c in ClientsRepository.LoadAll() orderby c.Name select new ComboBoxOptionGroup { Text = c.Name, Options = from p in c.Projects orderby p.Name select new ComboBoxOption {

我有一个LINQ查询,它获取嵌套对象的列表

from c in ClientsRepository.LoadAll()
orderby c.Name
select new ComboBoxOptionGroup
    {
    Text = c.Name,
    Options = from p in c.Projects
              orderby p.Name
              select new ComboBoxOption
              {
                  Text = p.Name,
                  Value = p.ID.ToString()
              }
    } 
不幸的是,这个LINQ查询导致num(客户机)+1个SQL查询。有没有什么优雅的方法可以重写它,使它只生成一个SQL查询


我的想法是获取客户订购的所有项目,并在两个嵌套的foreach循环中完成其余工作,但这似乎违背了LINQ设计时的优雅。有更好的选择吗?

您可能会搜索“join”操作符:

您可能会搜索“join”操作符:

如果
ClientsRepository.LoadAll()
是一个围绕查询的包装器,它实际上会进入数据库并检索数据(不返回
IQueryable
),那么您就卡住了。如果它返回查询的一部分(确实返回
IQueryable
),那么它应该是可能的

但是,如果不知道数据(或对象)上下文的位置和模型,就很难实现

通常情况下,我会希望做以下事情:

from client in dataContext.Clients
join p in dataContext.Projects on p.ClientId equals c.Id
  into projects
orderby client.Name
select new ComboBoxOptionGroup {
  Text = client.Name,
  Option = from p in projects
           orderby p.Name
           select new ComboBoxOption {
             Text = p.Name,
             Value = p.ID.ToString()
           }
}

如果
ClientsRepository.LoadAll()
是一个围绕查询的包装器,它实际上会进入数据库并检索数据(不会返回
IQueryable
),那么您就卡住了。如果它返回查询的一部分(确实返回
IQueryable
),那么它应该是可能的

但是,如果不知道数据(或对象)上下文的位置和模型,就很难实现

通常情况下,我会希望做以下事情:

from client in dataContext.Clients
join p in dataContext.Projects on p.ClientId equals c.Id
  into projects
orderby client.Name
select new ComboBoxOptionGroup {
  Text = client.Name,
  Option = from p in projects
           orderby p.Name
           select new ComboBoxOption {
             Text = p.Name,
             Value = p.ID.ToString()
           }
}

另一种可能的选择是使用
DataLoadOptions

DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Client>(c => c.Projects);
context.DeferredLoadingEnabled = false; // You may not need/want this line
context.LoadOptions = dlo;
DataLoadOptions dlo=newdataloadoptions();
dlo.LoadWith(c=>c.Projects);
context.DeferredLoadingEnabled=false;//您可能不需要/想要这条线路
context.LoadOptions=dlo;

我还没有测试过这种方法,但希望您能够不使用查询,减少必要的查询数量。

另一种可能的选择是使用
DataLoadOptions

DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Client>(c => c.Projects);
context.DeferredLoadingEnabled = false; // You may not need/want this line
context.LoadOptions = dlo;
DataLoadOptions dlo=newdataloadoptions();
dlo.LoadWith(c=>c.Projects);
context.DeferredLoadingEnabled=false;//您可能不需要/想要这条线路
context.LoadOptions=dlo;

我还没有测试过这种方法,但希望您能够不使用查询,减少必要的查询。

谢谢您的提示。我实际上知道join操作符,但我不知道它适用于本例。我不认为连接实际上是GroupJoin的结果。谢谢你的暗示。我实际上知道join操作符,但我不知道它适用于本例。我不认为连接实际上会导致GroupJoin在这里。有趣!我以前从未听说过这些。让我知道这是否对您有效-正如我所说,我还没有测试过它,所以我很好奇它的性能如何。很有趣!我以前从未听说过这些。让我知道这是否对您有效-正如我所说,我还没有测试过它,所以我很好奇它的性能如何。