Linq 获取组中的第一项和最后一项(如果存在)
我有一个场景,其中我的数据如下所示 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-05Linq 获取组中的第一项和最后一项(如果存在),linq,entity-framework,group-by,Linq,Entity Framework,Group By,我有一个场景,其中我的数据如下所示 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
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
书
---------------------------------
标题|返回日期
《了不起的盖茨比》2015-05-04
《了不起的盖茨比》2015-01-11
PI的寿命| 2015-04-04
PI的寿命| 2015-04-02
清洁规范| 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);
恶心。也许是一个更好的方法,但首先我想到了这一点。经过一点努力,我想出了这个。不确定在处理大型数据表时这会有多高效
[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; }
}
[测试]
public void FirstLastLinq()
{
var books=新列表
{
新书{Title=“Great Gatsby”,Returned=new DateTime(2015,04,03)},
新书{Title=“Great Gatsby”,Returned=new DateTime(2015,04,02)},
新书{Title=“Great Gatsby”,Returned=new DateTime(2015,04,01)},
新书{Title=“PI的生命”,返回=新日期时间(2015,03,05)},
新书{Title=“PI的生命”,返回=新日期时间(2015,03,04)},
新书{Title=“Clean Code”,返回=新日期时间(2015,02,02)},
};
var newBooks=books.GroupBy(b=>b.Title)。SelectMany(g=>g.OrderByDescending(b=>b.Returned)
其中(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);
}
私塾
{
公共字符串标题{get;set;}
返回的公共日期时间{get;set;}
}
获取第一个和最后一个归还日期,然后归还归还日期等于以下日期的书籍:
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
哎哟,看起来很吓人。无论如何,谢谢你的回答。谢谢你的建议格特。我想返回原始的Book对象,而不是匿名对象
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