Aggregate 子句 (Visual Basic)

向集合应用一个或多个聚合函数。

语法

Aggregate element [As type] In collection _  
  [, element2 [As type2] In collection2, [...]]  
  [ clause ]  
  Into expressionList  

组成部分

术语 定义
element 必需。 用于循环访问集合元素的变量。
type 可选。 element 的类型。 如果未指定类型,则从 collection 推断 element 的类型。
collection 必需。 指要操作的集合。
clause 可选。 一个或多个查询子句,例如 Where 子句,用于优化查询结果以应用聚合子句。
expressionList 必需。 一个或多个逗号分隔的表达式,用于标识要应用于集合的聚合函数。 可以向聚合函数应用别名,以指定查询结果的成员名称。 如果未提供别名,则使用聚合函数的名称。 例如,请参阅本主题后面关于聚合函数的部分。

注解

Aggregate 子句可用于在查询中包含聚合函数。 聚合函数对一组值执行检查和计算并返回单个值。 可以使用查询结果类型的成员访问计算值。 可以使用的标准聚合函数包括 AllAnyAverageCountLongCountMaxMinSum 函数。 熟悉 SQL 中的聚合的开发人员自然也熟悉这些函数。 本主题的以下部分将对其进行介绍。

聚合函数的结果作为查询结果类型的字段包含在查询结果中。 你可以为聚合函数结果提供别名,以指定将包含聚合值的查询结果类型的成员的名称。 如果未提供别名,则使用聚合函数的名称。

Aggregate 子句可以开始查询,也可以作为附加子句包含在查询中。 如果 Aggregate 子句开始查询,则结果是单个值,它是 Into 子句中指定的聚合函数的结果。 如果在 Into 子句中指定多个聚合函数,则查询返回具有单独属性的单个类型,以引用 Into 子句中每个聚合函数的结果。 如果 Aggregate 子句作为附加子句包含在查询中,则查询集合中返回的类型将具有单独的属性来引用 Into 子句中每个聚合函数的结果。

聚合函数

以下标准聚合函数可与 Aggregate 子句一起使用。

全部

如果集合中的所有元素都满足指定条件,则返回 true;否则返回 false。 以下是一个示例:

Dim customerList1 = Aggregate order In orders
                    Into AllOrdersOver100 = All(order.Total >= 100)

任意

如果集合中的任意元素满足指定条件,则返回 true;否则返回 false。 以下是一个示例:

Dim customerList2 = From cust In customers
                    Aggregate order In cust.Orders
                    Into AnyOrderOver500 = Any(order.Total >= 500)

平均值

计算集合中所有元素的平均值,或计算为集合中的所有元素提供的表达式。 以下是一个示例:

Dim customerOrderAverage = Aggregate order In orders
                           Into Average(order.Total)

计数

计算集合中的元素数。 你可以提供一个可选的 Boolean 表达式,以仅计算集合中满足条件的元素数。 以下是一个示例:

Dim customerOrderAfter1996 = From cust In customers
                             Aggregate order In cust.Orders
                             Into Count(order.OrderDate > #12/31/1996#)

指作为 Group ByGroup Join 子句的结果进行分组的查询结果。 Group 函数仅在 Group ByGroup Join 子句的 Into 子句中有效。 有关详细信息和示例,请参阅 Group By 子句Group Join 子句

LongCount

计算集合中的元素数。 你可以提供一个可选的 Boolean 表达式,以仅计算集合中满足条件的元素数。 以 Long 的形式返回结果。 有关示例,请参阅 Count 聚合函数。

最大值

计算集合中的最大值,或计算为集合中的所有元素提供的表达式。 以下是一个示例:

Dim customerMaxOrder = Aggregate order In orders
                       Into MaxOrder = Max(order.Total)

Min

计算集合中的最小值,或计算为集合中的所有元素提供的表达式。 以下是一个示例:

Dim customerMinOrder = From cust In customers
                       Aggregate order In cust.Orders
                       Into MinOrder = Min(order.Total)

Sum

计算集合中所有元素的总和,或计算为集合中的所有元素提供的表达式。 以下是一个示例:

Dim customerTotals = From cust In customers
                     Aggregate order In cust.Orders
                     Into Sum(order.Total)

示例

以下示例说明如何使用 Aggregate 子句将聚合函数应用于查询结果。

Public Sub AggregateSample()
    Dim customers = GetCustomerList()

    Dim customerOrderTotal =
        From cust In customers
        Aggregate order In cust.Orders
        Into Sum(order.Total), MaxOrder = Max(order.Total),
        MinOrder = Min(order.Total), Avg = Average(order.Total)

    For Each customer In customerOrderTotal
        Console.WriteLine(customer.cust.CompanyName & vbCrLf &
                         vbTab & "Sum = " & customer.Sum & vbCrLf &
                         vbTab & "Min = " & customer.MinOrder & vbCrLf &
                         vbTab & "Max = " & customer.MaxOrder & vbCrLf &
                         vbTab & "Avg = " & customer.Avg.ToString("#.##"))
    Next
End Sub

创建用户定义的聚合函数

通过向 IEnumerable<T> 类型添加扩展方法,可以在查询表达式中包含自己的自定义聚合函数。 然后,自定义方法可以对引用了聚合函数的可枚举集合执行计算或操作。 有关扩展方法的详细信息,请参阅扩展方法

例如,以下示例展示了一个自定义聚合函数,该函数计算一组数字的中值。 Median 扩展方法有两个重载。 第一个重载接受 IEnumerable(Of Double) 类型的集合作为输入。 如果为 Double 类型的查询字段调用 Median 聚合函数,则将调用此方法。 可以向 Median 方法的第二个重载传递任何泛型类型。 Median 方法的泛型重载采用第二个参数,该参数引用 Func(Of T, Double) Lambda 表达式,以将类型(来自集合)的值投影为 Double 类型的相应值。 然后,它将中值的计算委托给 Median 方法的另一个重载。 有关 lambda 表达式的详细信息,请参阅 Lambda 表达式

Imports System.Runtime.CompilerServices

Module UserDefinedAggregates

    ' Calculate the median value for a collection of type Double.
    <Extension()>
    Function Median(ByVal values As IEnumerable(Of Double)) As Double
        If values.Count = 0 Then
            Throw New InvalidOperationException("Cannot compute median for an empty set.")
        End If

        Dim sortedList = From number In values
                         Order By number

        Dim medianValue As Double

        Dim itemIndex = CInt(Int(sortedList.Count / 2))

        If sortedList.Count Mod 2 = 0 Then
            ' Even number of items in list.
            medianValue = ((sortedList(itemIndex) + sortedList(itemIndex - 1)) / 2)
        Else
            ' Odd number of items in list.
            medianValue = sortedList(itemIndex)
        End If

        Return medianValue
    End Function

    ' "Cast" the collection of generic items as type Double and call the 
    ' Median() method to calculate the median value.
    <Extension()>
    Function Median(Of T)(ByVal values As IEnumerable(Of T),
                          ByVal selector As Func(Of T, Double)) As Double
        Return (From element In values Select selector(element)).Median()
    End Function

End Module

以下示例展示了对 Integer 类型的集合和 Double 类型的集合调用 Median 聚合函数的示例查询。 对 Double 类型的集合调用 Median 聚合函数的查询调用 Median 方法的重载,该重载接受 Double 类型的集合作为输入。 对 Integer 类型的集合调用 Median 聚合函数的查询调用 Median 方法的泛型重载。

Module Module1

    Sub Main()
        Dim numbers1 = {1, 2, 3, 4, 5}

        Dim query1 = Aggregate num In numbers1 Into Median(num)

        Console.WriteLine("Median = " & query1)

        Dim numbers2 = {1.9, 2, 8, 4, 5.7, 6, 7.2, 0}

        Dim query2 = Aggregate num In numbers2 Into Median()

        Console.WriteLine("Median = " & query2)
    End Sub

End Module

另请参阅