使用group by将SQL转换为LINQ

时间:2014-06-02 19:58:47

标签: sql sql-server vb.net linq

我试图将以下sql转换为linq:

SELECT t.* FROM(SELECT mwfieldid,MAX([TimeStamp]) AS MaxValue, BatchDocumentID
   FROM mw_BatchField 
   GROUP BY mwfieldid,BatchDocumentID) x
  JOIN mw_BatchField t ON x.mwfieldid = t.mwfieldid
   AND x.MaxValue = t.TimeStamp
   and x.BatchDocumentID = t.BatchDocumentID 

到目前为止,我不得不将其转换为存储过程以使其工作。我宁愿知道如何在linq中正确地写这个。我尝试使用一个sql到linq转换器(http://www.sqltolinq.com/),它生成了这个代码中有错误的代码:(这些转换器是否有用?它似乎没有产生任何有用的几次尝试。)< / p>

From x In ( 
    (From mw_BatchFields In db.mw_BatchFields
    Group mw_BatchFields By 
      mw_BatchFields.MWFieldID,
      mw_BatchFields.BatchDocumentID
     Into g = Group 
    Select 
      MWFieldID,
      MaxValue = CType(g.Max(Function(p) p.TimeStamp),DateTime?),
      BatchDocumentID)
    )
Join t In db.mw_BatchFields
      On New With { .MWFieldID = CInt(x.MWFieldID), .MaxValue = CDate(x.MaxValue), .BatchDocumentID = CInt(x.BatchDocumentID) }
  Equals New With { .MWFieldID = t.MWFieldID, .MaxValue = t.TimeStamp, .BatchDocumentID = t.BatchDocumentID }
Select 
  BatchFieldID = t.BatchFieldID,
  BatchDocumentID = t.BatchDocumentID,
  MWFieldID = t.MWFieldID,
  TimeStamp = t.TimeStamp,
  value = t.value,
  DictionaryValue = t.DictionaryValue,
  AutoFilled = t.AutoFilled,
  employeeID = t.employeeID

对于这样一个简单的查询,似乎有很多代码,而且它不会编译。

1 个答案:

答案 0 :(得分:0)

因此,对于mwfieldid和BatchDocumentID的每个组合,您希望具有最高TimeStamp的行的所有列?这在LINQ中比在SQL中表达要容易得多,所以我对自动转换器正在制作它的过程并不感到惊讶。

你应该可以这样做:

Mw_BatchFields.GroupBy(x => new { x.Mwfieldid, x.BatchDocumentId })
    .SelectMany(x => x.Where(y => y.TimeStamp == x.Max(z => z.TimeStamp)))

如果组中有多个共享相同最大TimeStamp的行,则(与SQL一样)将为每个分组键返回多行。如果您只想要每行一行,您可以使用:

Mw_BatchFields.GroupBy(x => new { x.Mwfieldid, x.BatchDocumentId })
    .Select(x => x.OrderByDescending(y => y.TimeStamp).First())

修改 对不起,只是说你在VB工作,而不是C#,所以不是你想要的,但如果你能使用lambda语法风格,我认为上面的内容可以翻译为:

Mw_BatchFields.GroupBy(Function(x) New With {x.Mwfieldid, x.BatchDocumentId}).Select(Function(x) x.OrderByDescending(Function(y) y.TimeStamp).First())

Mw_BatchFields.GroupBy(Function(x) New With {x.Mwfieldid, x.BatchDocumentId}).SelectMany(Function(x) x.Where(Function(y) y.TimeStamp = x.Max(Function(z) z.TimeStamp)))