2

我有 2 个 SQL 语句,它们基本上做同样的事情,即根据一组记录的日期时间字段从表中检索最后一条记录。我正在使用数据优先的实体框架模型。我将如何使用 LINQ Lambda 函数编写这些 SQL 语句?

IE,

var u = db.AccessCodeUsage.Where(...).GroupBy(...)

而不是

var u = from a in db.AccessCodeUsage
        where ...
        group by ...

SQL 语句:

SELECT  *
FROM    AccessCodeUsage a  
WHERE   NOT EXISTS (SELECT  1 
                    FROM    AccessCodeUsage 
                    WHERE   LocationId = a.LocationId
                    AND     Timestamp > a.Timestamp)

SELECT    a.*
FROM    AccessCodeUsage a
WHERE   a.Timestamp = 
        (SELECT MAX(Timestamp)
        FROM    AccessCodeUsage
        WHERE   a.LocationId = LocationId
        AND     a.AccessCode = AccessCode
        GROUP   By LocationId, AccessCode)
4

2 回答 2

3

如果您需要方法调用形式,但发现它很难解决,请先使用其他语法:

from a in db.AccessCodeUsage
  orderby a.TimeStamp descending
  group a by a.LocationId into grp
  from g in grp select g.First();

然后通过一次一个地获取每个子句来转换为方法调用:

db.AccessCodeUsage
  .OrderByDescending(a => a.TimeStamp)
  .GroupBy(a => a.LocationId)
  .Select(g => g.First());

我可以从中锻炼第二个,而无需先写出 linq-syntax 表单:

db.AccessCodeUsage
  .OrderByDescending(a => a.TimeStamp)
  .GroupBy(a => new {a.LocationId, a.AccessCode})
  .Select(g => g.First());

(除非它不包含可能是错误的内容,因为如果时间戳不能保证唯一,则问题中给出的 SQL 可能包含一些额外的不适当结果)。

我现在无法检查生成的 SQL,但希望它的结果是等效的(如果不一定匹配)。在某些情况下,分组不能很好地转换为 SQL,但我当然不认为这是一个。

于 2012-08-16T22:05:36.373 回答
0

我最终使用了与第一个 SQL 语句相对应的以下内容。

// Retrieve only the latest (greatest value in timestamp field) record for each Access Code
var last = AccessCodeUsages.Where(u1 => !AccessCodeUsages
                           .Any(u2 => u2.LocationId == u1.LocationId &&
                                      u2.AccessCode == u1.AccessCode &&
                                      u2.Timestamp > u1.Timestamp));
于 2012-10-03T12:32:14.500 回答