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

发布于 2024-10-31 11:50:23 字数 2074 浏览 0 评论 0原文

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

这些是我的项目中的示例例程。 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服务器在服务器上运行整个聚合查询并使用函数SalesQry()

I have a reusable select query method called by two other methods.

These are the sample routines I have in my project. The SalesQry() method is actually very complex in our project.

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();            
}

The problem I am having is, when SalesByState() or SalesByArea() function is executed sql server is not running the aggregate query, instead it is just running this part returning large number of rows

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

and remaining part is being executed inside the application. If I don't call the function SalesQry()
and changed the query like below, sql server ran an aggregate query returning very less number of rows.

 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();

I need to share the code because it is very complex and used in many other places. How should I write the query to make the sql server run the entire aggregate query on the server and also use the function SalesQry()

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

不…忘初心 2024-11-07 11:50:23

编辑:您可能返回的是 IEnumerable 而不是 IQueryable。我第一次没注意到这一点。

我相信它被迫在客户端上执行聚合,因为它无法在数据库服务器上运行 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();   

Edit: It's probably that you're returning IEnumerable<Sales> instead of IQueryable<Sales>. I didn't catch that the first time.

I believe it's being forced to perform the aggregate on the client because it can't run new SalesAGG() on the database server. Try plucking it out with a Let statement, eg:

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();   

If that isn't working, then my next hunch is that it's the group by clause that groups on a newed-up object. Try using string concatenation as the group by criteria instead, eg:

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();   
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文