具有Max和Group By的子查询的LINQ版本

时间:2014-09-08 07:05:49

标签: sql vb.net entity-framework linq-to-entities where-in

如何使用LINQ to Entities完成以下查询。

SELECT [id] ,[value1], [value2], [dateValue]
FROM table
WHERE dateValue IN (
    SELECT MAX(dateValue)
    FROM table
    GROUP BY id
)

表中有多个条目具有相同的id,因此我只想要每个id中具有最大日期值的条目。此外,dateValue包含一个毫秒级的时间组件,不会重复。

我知道LINQ To Entities不支持IN关键字但是我已经读过你仍然可以使用context.tableName.Any()方法或在内部添加查询来处理子查询选择部分。

Using context = ContextProvider.GetContext()
    Dim table = context.tableName

    Dim query = _
        From rows In table _
        Select New ClassName With _
               { _
                   .Id = rows.Id, _
                   .Value1 = rows.Value1, _
                   .Value2 = rows.Value2, _
                   .DateValue = rows.DateValue _
               }

    Return query.ToList()
End Using

鉴于上述情况,我不确定查询中是否应该有Where table.Any(...,或者选择中的.DateValue = subquery是否应该得到我想要的内容。在任何一种情况下,我都不确定如何格式化表达式。

1 个答案:

答案 0 :(得分:1)

实际上你的sql已经不正确了,因为除了日期之外,子查询和主查询之间没有关系。如果您的ID为dateValue,即另一个ID的max-dateValue,则会使用错误的ID获取此记录。

因此,如果您希望每个ID具有最大日期的记录,我会这样做:

WITH CTE AS
(
    SELECT rn = ROW_NUMBER() OVER (PARTITION BY [id] ORDER BY [dateValue] DESC),
          [id] ,[value1], [value2], [dateValue]
    FROM table
)
SELECT [id] ,[value1], [value2], [dateValue]
FROM CTE
WHERE RN = 1

在LINQ中这应该有用(我不熟悉Linq-To-Entities):

Dim query = From row In table
            Group row By row.Id into idGrp
            Let MaxDatePerID = idGrp.Max(Function(r) r.DateValue)
            From idRow In idGrp
            Where idRow.DateValue = MaxDatePerID 
            Select New ClassName With 
            { 
               .Id = idRow.Id, 
               .Value1 = idRow.Value1, 
               .Value2 = idRow.Value2, 
               .DateValue = idRow.DateValue 
            }