如何将多个 LINQ to objects 请求合并为一个请求
How to combine mulitiple LINQ to objects requests into single one
我想将 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)
并没有让我更接近解决方案。
你可以用很有用?? ( 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;
您可以通过订购它们来表明偏好 - 例如:
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();
这取决于您使用的数据源和 LINQ 提供程序。
例如,如果您使用 LINQ 来 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();
我想将 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)
并没有让我更接近解决方案。
你可以用很有用?? ( 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;
您可以通过订购它们来表明偏好 - 例如:
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();
这取决于您使用的数据源和 LINQ 提供程序。
例如,如果您使用 LINQ 来 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();