2015-07-21 76 views
3

我有一個場景,我的數據看起來像這樣。獲取第一個項目和最後一個項目,如果它存在於一個組中

 
Books 
--------------------------------- 
title   | returnedDate 
Great Gatsby  | 2015-05-04 
Great Gatsby  | 2015-03-22 
Great Gatsby  | 2015-01-11 
Life of PI  | 2015-04-04 
Life of PI  | 2015-04-02 
Clean Code  | 2015-06-05 

我想每個組返回最先和最後一本書(按標題分類)在一個單一的LINQ語句。我知道我可以用這樣的linq查詢來獲得第一個或最後一個項目。

var books = dbContext.Books 
    .GroupBy(b => b.title) 
    .Select(g => g.OrderDescending().FirstOrDefault()); 

如果存在最後一項,我該如何獲得?

我最終的結果會是什麼樣子:

 
Books 
--------------------------------- 
title   | returnedDate 
Great Gatsby  | 2015-05-04 
Great Gatsby  | 2015-01-11 
Life of PI  | 2015-04-04 
Life of PI  | 2015-04-02 
Clean Code  | 2015-06-05 

回答

0

隨着一些擺弄,我想出了這個。不知道在處理大量數據表時這將會有多高效。

 [Test] 
    public void FirstLastLinq() 
    { 
     var books = new List<Book> 
     { 
      new Book { Title = "Great Gatsby", Returned=new DateTime(2015,04,03) }, 
      new Book { Title = "Great Gatsby", Returned=new DateTime(2015,04,02) }, 
      new Book { Title = "Great Gatsby", Returned=new DateTime(2015,04,01) }, 
      new Book { Title = "Life of PI", Returned=new DateTime(2015,03,05) }, 
      new Book { Title = "Life of PI", Returned=new DateTime(2015,03,04) }, 
      new Book { Title = "Clean Code", Returned=new DateTime(2015,02,02) }, 
     }; 

     var newBooks = books.GroupBy(b => b.Title).SelectMany(g => g.OrderByDescending(b => b.Returned) 
      .Where(b1 => b1.Returned == g.Min(b2 => b2.Returned) || 
       (b1.Returned == g.Max(b3 => b3.Returned) && g.Min(b4 => b4.Returned) != g.Max(b5 => b5.Returned)))); 

     Assert.IsNotNull(newBooks); 

    } 
    private class Book 
    { 
     public string Title { get; set; } 
     public DateTime Returned { get; set; } 
    } 
3
var books = dbContext.Books 
    .GroupBy(b => b.title) 
    .Select(g=>new { 
     Title=g.Key, 
     First=g.OrderByDescending(x=>x).FirstOrDefault(), 
     Last=g.OrderBy(x=>x).FirstOrDefault() 
    }); 

Results: 
title     | First | Last 
Great Gatsby | 2015-05-04 | 2015-01-11 
Life of PI   | 2015-04-04 | 2015-04-02 
Clean Code | 2015-06-05 | 2015-06-05 

如果你真的想它就像你問的話,那就有點困難:

var books = dbContext.Books 
    .GroupBy(b => b.title) 
    .Select(g=>new { 
     title=g.Key, 
     returnedDate=g.OrderByDescending(x=>x).FirstOrDefault() 
    }).Concat(
     dbContext.Books 
     .GroupBy(b => b.title) 
     .Where(g=>g.Count()>1) 
     .Select(g=>new { 
     title=g.Key, 
     returnedDate=g.OrderBy(x=>x).FirstOrDefault() 
     }) 
    ).OrderBy(c=>c.title).ThenDescendingBy(c=>c.returnedDate); 

呸。可能是更好的方法,但首先想到的。

+0

哎喲,看起來很嚇人。無論如何感謝您的答案。 – Andrew

2

有可能通過獲得第一和最後的返回日期,然後返回的書籍,歸還日期是等於這些:

from b in dbContext.Books 
group b by b.title into bg 
let first = bg.OrderByDescending (b => b.returnedDate).FirstOrDefault().returnedDate 
let last = bg.OrderBy (b => b.returnedDate).FirstOrDefault().returnedDate 
from b in bg 
where b.returnedDate == first || b.returnedDate == last 
orderby b.title, b.returnedDate 
select b 
+0

感謝Gert的建議。我想返回原始Book對象而不是匿名對象 – Andrew

+1

Easy。查看編輯。 –

相關問題