Aggregate是否存在致命缺陷,因为每个into子句是单独执行的?

时间:2012-09-04 13:39:57

标签: vb.net linq linq-to-sql aggregate-functions aggregate

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

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

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

但是,此答案实际上会在单独Min和Max中的每一个(如果您包括其他汇总函数,例如CountAverage SQL查询。这可以在LINQPad中轻松看到。

是否存在LINQPad未显示的事务(或其他使这些查询成为原子的事件),或者这是一个等待发生的竞争条件? (因此,您必须执行上述问题的答案中显示的技巧,以强制返回多个聚合的单个查询。)

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

<子> (我也说“显而易见”,因为对我来说显而易见的答案Aggregate p In Plants Into Min(p.ZoneMin), Max(p.ZoneMin)实际上检索了整个表两次,即使在优化之后,然后使用Linq-to-Entities Min和{{1}获得结果:-()

我认为Max不是特定于VB的,但看起来C#没有此查询表达式,所以我已将更改为

2 个答案:

答案 0 :(得分:1)

虽然它不使用Aggregate关键字,但您可以使用以下语法在单个查询中执行多个功能:

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 to Objects在客户端上执行Max。

答案 1 :(得分:0)

回答我更广泛的问题:由于生成单独的SQL查询而没有事务,Aggregate是否被打破?

如果你没有仔细调整你的查询只能产生一个SELECT,那么所有LINQ都会导致这种情况,而这可能是不可能的,没有“放弃”,在单个中检索更大的结果查询然后使用Linq-to-Objects来聚合或以其他方式操纵数据。例如This 'query'

因此,通常情况下,程序员可以确保在可能导致多个查询的LINQ查询周围添加事务。我们只需要确定哪些LINQ查询可以转换为多个SQL查询。