如何在LINQ中编写聚合查询,重用部分选择代码

时间:2011-04-07 20:34:21

标签: c# linq tsql linq-to-sql

我有一个可重用的select查询方法,由另外两个方法调用。

这些是我项目中的示例程序。 SalesQry()方法在我们的项目中实际上非常复杂。

Private IEnumerable<Sales> SalesQry(SalesDataContext sContext, int customerID)
{
   return 
      from SALE in sContext.Sales
      where SALE.CustomerID = customerID
      select SALE
}

Public List<SalesAGG> SalesByArea()
{
   SalesDataContext oSContext = new SalesDataContext (.....);

  return from SALE in SalesQry(sContext,1230)
              group SALE by
              new
              {
                Type = SALE.SaleType,
                Area = SALE.Area
              }   into aggAREA
             select new  SalesAGG()
             {
                Type = aggAREA.Key.Type,
                Place =  aggAREA.Key.Area,
                TotalSales = aggAREA.Count()
             }.ToList();     
}

Public List<SalesAGG> SalesByState()
{
   SalesDataContext oSContext = new SalesDataContext (.....);

  return from SALE in SalesQry(sContext,1230)
              group SALE by
              new
              {
                Type = SALE.SaleType,
                State = SALE.State
              }   into aggSTATE
             select new  SalesAGG()
             {
                Type = aggSTATE.Key.Type,
                Place =  aggSTATE.Key.State,
                TotalSales = aggSTATE.Count()
             }.ToList();            
}

我遇到的问题是,当执行SalesByState()或SalesByArea()函数时,sql server没有运行聚合查询,而只是运行此部分返回大量行

from SALE in sContext.Sales
          where SALE.CustomerID = customerID
          select SALE

其余部分正在应用程序内部执行。如果我不调用函数SalesQry() 并且更改了下面的查询,sql server运行了一个返回非常少行数的聚合查询。

 from SALE in sContext.Sales
 where SALE.CustomerID = 1230
 group SALE by
  new
  {
     Type = SALE.SaleType,
     State = SALE.State
   }   into aggSTATE
  select new  SalesAGG()
  {
    Type = aggSTATE.Key.Type,
    Place =  aggSTATE.Key.State,
   TotalSales = aggSTATE.Count()
  }.ToList();

我需要共享代码,因为它非常复杂并且在许多其他地方使用。我应该如何编写查询以使sql server在服务器上运行整个聚合查询,并使用函数SalesQry()

1 个答案:

答案 0 :(得分:3)

修改:您可能正在返回IEnumerable<Sales>而不是IQueryable<Sales>。我第一次没有抓到它。

我认为它被迫在客户端上执行聚合,因为它无法在数据库服务器上运行new SalesAGG()。尝试使用Let语句将其删除,例如:

return from SALE in SalesQry(sContext,1230)
          group SALE by
          new
          {
            Type = SALE.SaleType,
            Area = SALE.Area
          }   into aggAREA
         let totalSales = aggAREA.Count()
         select new  SalesAGG()
         {
            Type = aggAREA.Key.Type,
            Place =  aggAREA.Key.Area,
            TotalSales = totalSales
         }.ToList();   

如果这不起作用,那么我的下一个预感是它是一个group by子句,它在一个新建对象上进行分组。请尝试使用字符串连接作为group by条件,例如:

return from SALE in SalesQry(sContext,1230)
          group SALE by SALE.SaleType + SALE.Area into aggAREA
         select new  SalesAGG()
         {
            Type = aggAREA.First().Type,
            Place =  aggAREA.First().Area,
            TotalSales = aggAREA.Count()
         }.ToList();