在LINQ查询中分组

时间:2014-04-13 21:16:45

标签: vb.net linq entity-framework

给出一个包含数千行数据的表格,如下面的示例所示

Id  Date        SymbolId    NumOccs HighProjection  LowProjection   ProjectionTypeId
1   2014-04-09    28           45        1.0765        1.0519            1
2   2014-04-10    5            44        60.23         58.03             1
3   2014-04-11    29           77        1.026         1.0153            1

和一个定义为

的类
Public Class ProjectionPerformance
    Public symbolId As Integer
    Public Name as String
    Public Date as String       
    Public ActualRange as Decimal
End Class

我正在尝试为每个symbolId返回以下内容;
symbolId(来自此表)
符号名称(来自符号表)
实际范围(高投影 - 低投影)

这可以在一个查询中完成,因为我基本上需要一个Dictionary(Of Integer,List(Of ProjectionPerformance)),其中整数是symbolId,List是从查询生成的吗?

更新
为了更清楚一点,这是我到目前为止所做的,但包含两个LINQ迭代

Public Shared Function GetRangeProjectionPerformance(Optional daysToRetrieve As Integer = 100) As Dictionary(Of Integer, List(Of ProjectionPerformance))

Dim todaysDate As Date = DateTime.Now.Date
Dim lookbackDate As Date = todaysDate.AddDays(daysToRetrieve * -1)
Dim temp As New Dictionary(Of Integer, List(Of ProjectionPerformance))


Using ctx As New ProjectionsEntities()
    Dim query = (From d In ctx.projections
                 Where d.SymbolId <= 42 AndAlso d.Date >= lookbackDate
                 Join t In ctx.symbols On d.SymbolId Equals t.Id
                 Let actualRange = d.HighProjection - d.LowProjection
                 Select New With {
                    d.Date,
                    d.SymbolId,
                    t.Name,
                    actualRange}).GroupBy(Function(o) o.SymbolId).ToDictionary(Function(p) p.Key)

    For Each itm In query
        Dim rpp As New ProjectionPerformance
        Dim rppList As New List(Of ProjectionPerformance)
        If itm.Value.Count > 0 Then
            For x As Integer = 0 To itm.Value.Count - 1
                Dim bb As Integer = Convert.ToInt32(itm.Value(x).SymbolId)
                With rpp
                    .SymbolId = bb
                    .ProjectionDate = itm.Value(x).Date.ToString()
                    .Name = itm.Value(x).Name
                    .ProjectedRange = itm.Value(x).actualRange
                End With
                rppList.Add(rpp)
            Next
        End If

        temp.Add(itm.Key, rppList)
    Next
End Using
Return temp

结束功能

2 个答案:

答案 0 :(得分:0)

我将在C#中回答,但我认为无论如何你都会得到它的要点。基本上,您可以按SymbolId分组,构建对象图,然后使用ToDictionary使用Key创建dictionary

var result = (From d In _projectionEntities.projections
                 Where d.SymbolId <= 42
                 group d by d.SymbolId into g
                 select new {
                         SymbolId = g.Key,
                           ProjectionPerformances = 
                                       g.Select(gg=>new ProjectionPerformance{
                                                   SymbolId = gg.SymbolId,
                                                   Name = gg.Symbol.Name,
                                                   rpDate = gg.Date.ToString(),
                                                   ActualRange = gg.HighProjection - gg.LowProjection
                                                  })
                      .ToDictionary(g=>g.SymbolId);

答案 1 :(得分:-1)

尝试

Dim Result = (From d In _ProjectionEntities.projections
             Join t In _projectionEntities.symbols On d.SymbolId Equals t.Id
             Where d.SymbolId <= 42
             Select New With {.SymbolID = d.SymbolID
                              .Date = d.Date
                              .Name = t.Name
                              .ActualRange = d.HighProjection - d.LowProjection})