LINQ GroupBy用法

时间:2012-09-21 19:16:29

标签: vb.net linq lambda

我用它来按日期排序我的所有记录:

Dim myData = db.Tbl_Exercises.Where(Function(x) x.Exercise_Employee_ID).OrderBy(Function(x) x.Exercise_Create_Date)

我循环使用:

    For Each i As Tbl_Exercise In myData

        data.Add(New Object() {i.Tbl_Exercise_Type.ExType_Desc, i.Exercise_Duration})

    Next

如何按i.Tbl_Exercise_Type.ExType_Desc进行分组,以便我没有重复项?

我试过了:

Dim myData = db.Tbl_Exercises.Where(Function(x) x.Exercise_Employee_ID).GroupBy(Function(x) x.Exercise_Type_ID)

但是,我不知道如何在我的循环中访问变量。

谢谢。

修改

<EmployeeAuthorize()>
Function ExercisePieChartData() As JsonResult

    ' get current employee's id
    Dim db1 As EmployeeDbContext = New EmployeeDbContext
    Dim user1 = db1.Tbl_Employees.Where(Function(e) e.Employee_EmailAddress = User.Identity.Name).Single()
    Dim empId = user1.Employee_ID

    Dim activityGroups = db.Tbl_Exercises.Where(Function(x) x.Exercise_Employee_ID = empId).GroupBy(Function(x) x.Exercise_Type_ID)

    Dim data = New List(Of Object)

    ' columns (headers)
    data.Add(New Object() {"Type", "Duration"})

    ' Iterate through each collection of activities, grouped by activity types
    For Each group In activityGroups

        ' Iterate through each Tbl_Exercise in the group
        For Each activity In group

            ' Do something with an individual element
            data.Add(New Object() {activity.Tbl_Exercise_Type.ExType_Desc, activity.Exercise_Duration})

        Next

    Next

    Return Json(data, JsonRequestBehavior.AllowGet)

End Function

修改

    ' Iterate through each collection of activities, grouped by activity types
    For Each group In activityGroups

        Dim type = ""
        Dim duration = 0

        ' Iterate through each Tbl_Exercise in the group
        For Each activity In group

            ' Do something with an individual element
            type = activity.Tbl_Exercise_Type.ExType_Desc
            duration += activity.Exercise_Duration

        Next

        data.Add(New Object() {type, duration})

    Next

1 个答案:

答案 0 :(得分:1)

注意:您的示例并不完全清楚,因此我将对您尝试使用我的解决方案进行一些假设。我会根据需要修改它,因为有更多细节可供使用。

从它看起来,对于每个员工,你试图获得他们已经完成的运动类型的集合,并且对于每种类型的运动,你还需要他们花费在执行这些运动上的时间长度的集合。活动。

我将假设Tbl_Exercises中的一行看起来像这样:

Public Class Tbl_Exercise

    Public Property Exercise_Employee_ID As Integer
    Public Property Exercise_Type_ID As Integer
    Public Property Exercise_Type_Desc As String
    Public Property Exercise_Duration As Integer

End Class

你在最后做的尝试非常接近,你只需要在创建后实际使用分组。

此处GroupBy方法返回的内容实际上是IGrouping(Of Integer, Tbl_Exercise),其中键是Exercise_Type_ID,值是按键分组的行集合。要访问它们非常简单,您只需要将分组视为一种嵌套集合:

    Dim activityGroups = db.Tbl_Exercises.Where(Function(x) x.Exercise_Employee_ID = employeeId).GroupBy(Function(x) x.Exercise_Type_ID)

    ' Iterate through each collection of activities, grouped by activity types
    For Each group In activityGroups

        ' Iterate through each Tbl_Exercise in the group
        For Each activity In group

            ' Do something with an individual element
            Console.WriteLine(activity.Exercise_Duration)

        Next

    Next

显然,您可能希望执行与打印单个集合不同的操作,您可能希望将每个分组的数据绑定到它们自己的DataGrid,以便您可以单独显示它们。您可能希望按日期对每个分组进行排序,或者您可能只想要每个组中的第一个元素。一旦了解了分组的结构,就可以很容易地完成您正在寻找的内容。

修改

如果您只想在分组中聚合某些字段,则无需借助循环结果即可轻松完成。只需在Select之上添加对GroupBy的通话,您就可以将结果投影到所需的汇总表单中:

Dim data = db.Tbl_Exercises _
                .Where(Function(x) x.Exercise_Employee_ID = empId) _
                .GroupBy(Function(x) x.Exercise_Type_Desc) _
                .Select(Function(x)
                            Return New With {
                                ' x.Key will give you access to the value that the grouping is grouped by
                                .Exercise_Type_Desc = x.Key,
                                .TotalDuration = x.Sum(Function(y) y.Exercise_Duration)
                            }
                        End Function)