Как написать агрегированный запрос в LINQ с повторным использованием части кода выбора - PullRequest
1 голос
/ 08 апреля 2011

У меня есть метод запроса на повторное использование, который вызывается двумя другими методами.

Это примеры процедур, которые есть в моем проекте.Метод 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 не выполняет агрегированный запрос, вместо этогоон просто выполняет эту часть, возвращая большое количество строк

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

, а оставшаяся часть выполняется внутри приложения.Если я не вызову функцию SalesQry () и не изменил запрос, как показано ниже, сервер SQL запустил агрегированный запрос, возвращающий очень меньшее количество строк.

 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 выполнял весь агрегатный запрос на сервере, а также использовал функцию SalesQry ()

1 Ответ

3 голосов
/ 08 апреля 2011

Редактировать: Вероятно, вы возвращаете 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();   
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...