如何在 LINQ 中重用部分选择代码编写聚合查询
我有一个可重用的选择查询方法,由另外两种方法调用。
这些是我的项目中的示例例程。 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
编辑:您可能返回的是
IEnumerable
而不是IQueryable
。我第一次没注意到这一点。我相信它被迫在客户端上执行聚合,因为它无法在数据库服务器上运行
new SalesAGG()
。尝试使用Let
语句将其取出,例如:如果这不起作用,那么我的下一个预感是它是对新的分组进行分组的
group by
子句目的。尝试使用字符串连接作为group by
标准,例如:Edit: It's probably that you're returning
IEnumerable<Sales>
instead ofIQueryable<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 aLet
statement, eg: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 thegroup by
criteria instead, eg: