2012-09-04 12 views
12

当用作具有多个Into子句的Linq表达式的第一个(外部)子句时,VB.NET的Aggregate查询是否有致命缺陷,因为每个Into子句都是分别执行的?由于每个分词都单独执行,因此是否具有集体致命缺陷?

的“明显的”答案SELECT MIN(ZoneMin), MAX(ZoneMin) FROM Plant in LINQ to SQL

Dim limits = Aggregate p In Plants Select p.ZoneMin Into Min(), Max() 

然而,这个答案其实检索每个MinMax(如果你包括像CountAverage其它集合函数)在单独 SQL查询。这可以很容易地在LINQPad中看到。

LINQPad没有显示一个事务(或其他使这些查询为原子的东西),还是这是一个等待发生的竞争条件? (所以你必须做上述问题的答案中显示的技巧来强制一个查询返回多个聚合。)

总之,是否有一个使用Aggregate的LINQ-to-SQL查询返回多个聚合函数在单个(或至少“原子”)查询?

(我也说“很明显”,因为明显的答案对我来说,Aggregate p In Plants Into Min(p.ZoneMin), Max(p.ZoneMin),实际上获得了整个表的两倍,优化甚至当,然后使用LINQ到实体MinMax以获得结果: - ()

我以为Aggregate不是VB-具体,但它看起来像C#没有这个查询表达式,所以我已经改变了

+0

您可能可以通过跟踪SQL服务器本身来验证查询是否在事务中,它应该显示它(但我不能100%确定它)。但是,如果性能不是主要问题,则最好读取整个数据集并进行汇总(基本上,处理数据的快照)。 – Alex

+0

请注意,这就是我希望我的原始'Into Min(p.ZoneMin)'查询会优化到,因为查询的SQL部分现在是相同的。也许JITter可能仍然可以看到,但LINQPad的/ o +没有。 –

+0

虽然你只是用SQL支持的函数进行聚合,但最好是按照“不变的技巧分组”来让数据库进行聚合。 –

回答

0

要回答我的更广泛的问题:是Aggregate打破了生产单独的SQL查询没有交易?

所有的LINQ都可能导致,如果你不仔细调整你的查询只会导致一个SELECT,这可能是不可能的,没有“放弃”,检索一个查询中的较大结果,然后使用Linq-to-Objects来聚合或以其他方式处理数据。例如,This 'query'

因此,一般来说,程序员应确保交易是在可能导致多个查询的LINQ查询中添加的。我们只需要知道哪些LINQ查询可以转换为多个SQL查询。

1

Alt键。霍夫它不使用以下语法使用聚合关键字,你可以在一个单一的查询做多的功能:

Dim query = From book In books _ 
    Group By key = book.Subject Into Group _ 
    Select id = key, _ 
     BookCount = Group.Count, _ 
     TotalPrice = Group.Sum(Function(_book) _book.Price), _ 
     LowPrice = Group.Min(Function(_book) _book.Price), _ 
     HighPrice = Group.Max(Function(_book) _book.Price), _ 
     AveragePrice = Group.Average(Function(_book) _book.Price) 

目前确实出现了与总条款执行的问题虽然。考虑以下来自Northwind的查询:

Aggregate o in Orders 
into Sum(o.Freight), 
Average(o.Freight), 
Max(o.Freight) 

这会发出3个数据库请求。前两个执行单独的汇总子句。第三个将整个表拉回到客户端,并通过Linq将对象上的Max执行到客户端。

+1

是的,如果你将它改为'Group By key = 0 Into Group'(并放弃不需要的'id = key,'),你会得到我在问题的答案中描述的“按常量分组”提到,允许在整个表格上进行聚合。 –

+0

在我的示例中,我确实希望分组。如果你想把它放在整个桌子上,那么你的不变技巧就可以正常工作。 –

+0

我认为你的后一点与'Freight'类型有关,并且出于某种原因,Linq认为SQL的'MAX'可能返回与它认为'Max'应该返回的值不同的值。但_3__paparate__数据库请求_是我的问题所关心的。 –

相关问题