2017-02-11 74 views
0

我有這樣的LINQ查詢來選擇各組的第一個記錄:LINQ,每個組中第一個記錄只有當條件滿足

repo.GroupBy(x => x.Revision, (key, g) => g.OrderBy(y => y.CreationDate).First()) 

現在我要選擇的每個組僅在第一個記錄記錄滿足以下條件:

!x.Terminated 

很顯然,我可以在哪裏沒有附加到我的GroupBy因爲它返回一個對象,我想能夠檢查的情況在我的數據庫,而不必把每個每月的第一個記錄從那裏開始記憶和操作。

** 編輯

一組共享相同版本在我的設計記錄,意味着其在同一註冊,但編輯多次。這樣,具有更新的創建日期的記錄是該寄存器的實際修訂或版本,並且該組中的其餘記錄是歷史記錄。我的問題是,我只將組中的實際修訂標記爲已終止,因此無法在按照創建日期對每個組進行排序並僅選擇第一條記錄之前通過終止功能進行過濾。

現在作爲解決我的問題的方法,我將標記整個組作爲每次終止寄存器時終止,以便稍後可以在分組之前過濾終止的記錄,按日期排序並選擇每個組的第一條記錄正如@Jon Skeet和@ThomasAndreèLian所建議的那樣。

我會讓問題沒有被接受的答案一段時間,也許有人可以建議其他的東西,允許在分組,排序和選擇每個組的第一個記錄後,通過終止功能進行過濾。

+3

目前尚不清楚是否要完全* *排除終止記錄......如果是這樣,爲什麼不直接使用'repo.Where(X =>!x.Terminated).GroupBy(...)'。 –

+0

你能解釋一下爲什麼你不在'GroupBy'之後添加'Where' *嗎?謝謝 – 2017-02-11 22:57:00

+0

@ user1892538編譯器給我以下錯誤:'System.Linq.IQueryable '不包含「Where」和最佳擴展方法重載的定義'System.Linq.Enumerable.Where (System.Collection.Generic .IEnumerable ,System.Func )」具有一些無效參數。 –

回答

1

Linq方法,返回IQueryable<T>,是懶惰評估和未實現。

這意味着您實際上可以添加where條件,並且整個表達式樹將相應地更新。之前發生SQL轉換(由DB提供者)。

你錯過了執行流程的一個重要方面:生成的數據庫命令從數據庫檢索只有當你枚舉集合。

鏈接一個Where後Linq中的一個Group不會導致內存濾波但在HAVING條款,正是你在問什麼。

流暢的版本可以簡化爲

repo.GroupBy(x => x.Revision) 
.Select(x => x 
    .OrderBy(y => y.CreationDate) 
    .First()) 
.Where(x => !x.Terminated) 

或查詢版本應該是

var query = from rp in repo 
group rp by rp.Revision into grouped 
where !grouped.OrderBy(y => y.CreationDate).First().Terminated 
select grouped.OrderBy(y => y.CreationDate).First(); 

當然這取決於數據庫提供商,如果它能夠翻譯上面的查詢到SQL通過類映射:確實可能很難。

+0

我已經修改了流暢的版本(看它第一次),並增加了一個查詢版本(如果前者失敗)。 – 2017-02-12 13:28:46

+0

流利的版本工作得很好,這正是我一直在尋求的。謝謝。 –

0

我會認爲這會做到這一點。

repo.Where(x => !x.Terminated) 
     .GroupBy(x => x.Revision, (key, g) => g.OrderBy(y => y.CreationDate).First()) 

據我瞭解您無論如何要消除所有的Terminated元素(開頭還不如做)。

相關問題