如何将多个LINQ对对象的请求合并为一个
本文关键字:合并 一个 请求 对象 LINQ | 更新日期: 2023-09-27 18:06:54
我想将GetCurrentAuction重写为单个LINQ请求:
private AuctionInfo GetCurrentAuction()
{
var auctions = Auctions.List().ToList();
var liveAuction = auctions
.Where(AuctionIsLive)
.OrderBy(a => a.StartDate)
.FirstOrDefault();
if (liveAuction != null)
{
return liveAuction;
}
var openAuction = auctions
.Where(AuctionIsOpen)
.OrderBy(a => a.StartDate)
.FirstOrDefault();
if (openAuction != null)
{
return openAuction;
}
// next upcoming auction
return auctions
.Where(a => a.StartDate >= DateTime.UtcNow)
.OrderBy(a => a.StartDate)
.FirstOrDefault();
}
private bool AuctionIsLive(AuctionInfo auction)
{
// WorkflowStage is int
return auction.WorkflowStage == LIVE_WORKFLOW_STAGE;
}
private bool AuctionIsOpen(AuctionInfo auction)
{
return auction.WorkflowStage == OPEN_WORKFLOW_STAGE;
}
有人能建议如何实现这一点吗?看起来使用auctions.GroupBy(a => a.WorkflowStage)
并没有让我更接近解决方案。
您可以通过对它们进行排序来指示偏好-例如:
return
Auctions.List().ToList() //--> ToList() not needed here?
.Where
( a =>
AuctionIsLive(a) ||
AuctionIsOpen(a) ||
a.StartDate >= DateTime.UtcNow
)
.OrderBy
( a =>
AuctionIsLive( a ) ? 0 :
AuctionIsOpen( a ) ? 1 : 2
)
.ThenBy( a => a.StartDate )
.FirstOrDefaut();
你可以使用非常有用的?? ?(https://msdn.microsoft.com/en-us/library/ms173224.aspx)操作符并实现:
var result = auctions.Where(AuctionIsLive).OrderBy( x => x.StartDate).FirstOrDefault() ??
auctions.Where(AuctionIsOpen).OrderBy( x => x.StartDate).FirstOrDefault() ??
auctions.Where(a => a.StartDate >= DateTime.UtcNow).OrderBy(a => a.StartDate).FirstOrDefault();
return result;
这取决于你正在使用的数据源和LINQ提供程序。例如,如果您使用LINQ to SQL,则首选的方法是使用Expressions
来节省内存,并最终得到类似于@fankyCatz的答案:
return Auctions.Where(a => a.WorkflowStage == LIVE_WORKFLOW_STAGE).OrderBy(x => x.StartDate).FirstOrDefault() ??
Auctions.Where(a => a.WorkflowStage == OPEN_WORKFLOW_STAGE).OrderBy(x => x.StartDate).FirstOrDefault() ??
Auctions.Where(a => a.StartDate >= DateTime.UtcNow).OrderBy(a => a.StartDate).FirstOrDefault();
然而,只使用LINQ to Objects,我最终会得到类似于@Clay的答案,只是会提高映射的可读性:
public static Dictionary<int, Func<AuctionInfo, bool>> Presedence =
new Dictionary<int, Func<AuctionInfo, bool>>
{
{ 0, a => a.WorkflowStage == LIVE_WORKFLOW_STAGE },
{ 1, a => a.WorkflowStage == OPEN_WORKFLOW_STAGE },
{ 2, a => a.StartDate >= DateTime.UtcNow },
};
//in your GetCurrentAuction()
return Auctions.Where(a => Presedence.Any(p => p.Value(a)))
.OrderBy(a => Presedence.First(p => p.Value(a)).Key)
.ThenBy(a => a.StartDate)
.FirstOrDefault();