所以我有一个LINQ(to SQL)查询,它将信息从数据库提取到网格中。有一个函数可以根据当前的滤波器参数来聚合网格数据,这些参数将对网格数据中重复出现的“X”的数量进行求和。
例如,假设网格显示客户对杂货店的要求。原始数据可能会显示以下内容:
Date | Name | No. Prod | Total $
--------------------------------------------
01/02/13 | Customer A | 4 products | $23.00
01/02/13 | Customer B | 2 products | $3.26
01/02/13 | Customer C | 7 products | $47.42
01/16/13 | Customer A | 3 products | $26.22
单击clients列的求和函数将显示以下网格数据:
Cnt| Name | Tot. Prod | Total $
--------------------------------------
2 | Customer A | 7 products | $49.22
1 | Customer B | 2 products | $3.26
1 | Customer C | 7 products | $47.42
我的问题是我在LINQ查询中执行求和逻辑。我认为这会很快......但恰恰相反。这是一个样本。
Expression<Func<OrdersView, bool>> filter;
filter = m => m.RecordCreated >= fromDate && m.RecordCreated <= toDate && m.DepartmentID == _depID;
var ClientAggOrders = dataContext.OrdersView
.Where(filter)
.GroupBy(m => m.Name)
.Select(gr => new
{
Name = gr.Key,
Count = gr.Where(s => s.ID != null).Count(),
id = gr.Select(s => s.ID),
S1 = gr.Sum(s => s.Tare < s.Gross ? s.Tare : s.Gross),
S2 = gr.Sum(s => s.Tare < s.Gross ? s.Gross : s.Tare),
NetWeight = gr.Sum(s => s.NetWeight),
Price = gr.Sum(s => s.NetPrice)
}
).ToList();
我的问题是,为什么这么糟糕的做法? LINQ允许在SELECT子句中使用这些表达式,但是执行所花费的时间超出了荒谬的程度,我认为它在任何真实场景中都没有用处。
我是否使用LINQ错误,我应该将我的逻辑移到查询之外还是可以在LINQ中进行优化和完成?谢谢你的建议!
答案 0 :(得分:4)
您可以使用LINQPad查看生成的SQL。
由于LINQ to SQL的工作方式,id = gr.Select(s => s.ID)
会导致为每个组执行子查询。删除它,然后在GroupBy中获取ID +名称:.GroupBy(m => new{m.ID, m.Name})
您应该会发现生成的SQL现在将是单个语句,而不是主语句加上每个组的语句。
答案 1 :(得分:0)
仅在内存中执行分组?解决你的问题?
var ordersView =
dataContext.OrdersView
.Where(m => m.RecordCreated >= fromDate && m.RecordCreated <= toDate && m.DepartmentID == _depID)
.ToList();
var ClientAggOrders = ordersView.GroupBy(m => m.Name).Select(gr => new
{
Name = gr.Key,
Count = gr.Where(s => s.ID != null).Count(),
id = gr.Select(s => s.ID),
S1 = gr.Sum(s => s.Tare < s.Gross ? s.Tare : s.Gross),
S2 = gr.Sum(s => s.Tare < s.Gross ? s.Gross : s.Tare),
NetWeight = gr.Sum(s => s.NetWeight),
Price = gr.Sum(s => s.NetPrice)
}).ToList();