2012-08-16 65 views
2

我有2條基本上做同樣的事情的SQL語句,也就是說,從基於一組記錄的日期時間字段的表中檢索最後一條記錄。我正在使用數據優先的實體框架模型。我如何使用LINQ Lambda函數編寫這些SQL語句中的任何一個?如何編寫linq語句來獲取一組記錄的最後一個

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) 

回答

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)); 
3

如果您需要有方法調用的形式,但發現它非常棘手的工作out,則先使用其他語法:

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的語法形式第一:

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

(除了它不包括什麼可能是一個錯誤,因爲如果時間戳不保證是唯一的,問題中給出的SQL可能包含一些額外的不適當結果)。

我無法檢查現在生成的SQL,但它應該有望在結果上相當(如果不一定匹配)。有些情況下,分組不會轉換爲SQL,但我當然不會認爲這將是一個。

+0

好帖子,我有一個類似的問題,但在GroupBy()中使用匿名類型,因爲你已經允許我得到我需要的。 – 2012-08-17 09:08:12

+0

酷@PeadarDoyle。我用'GroupBy()'給出的一條建議是,如果你不確定如何將它轉換成一個好的單個查詢,總是值得分析它是如何工作的。有些使用不能變成只有一個查詢,並且對數據庫性能的影響是可怕的(更糟糕的是,它對測試數據通常很好,對實際數據的損害也很小)。在這個例子中,我會說它*可能*應該是好的,但我會檢查反正... – 2012-08-17 09:14:54

+0

如果你*發現查詢被轉換成大量的SQL查詢把'.AsEnumerable()'之前'.GroupBy()'。通常情況下,將'.AsEnumerable()'放到支持數據庫的Linq查詢中,會導致性能下降(數據庫工作量減少,流量增加,.NET工作量增加),但是'.GroupBy()'那些不能很好地轉換的是一個例外,在這個過程的早期步驟中將它移動到.NET是一個性能上的勝利(不是很小的一個,可能是因爲太慢而無法用於快速注意)。 – 2012-08-17 09:17:33

相關問題