[英]How to get the sum of the volume of highest and lowest priced items in linq
我試圖寫的實際查詢比標題所暗示的要復雜一些。 我有一個這樣的訂單列表: List<Order>
,訂單如下:
public class Order
{
private StockCodes _stockCode;
private bool _bidSide;
private int _volume;
private decimal _price;
}
我需要在給定特定股票代碼的情況下公布最佳買入價和成交量以及最佳賣出價和成交量。 最佳報價定義為bidSide為true的最高價格。 最佳賣價定義為bidSide為false的最低價格。
例如,給出股票代碼“ABC”的以下數據:
{ bidSide: true, volume: 25, price: 25 }
{ bidSide: true, volume: 25, price: 25 }
{ bidSide: true, volume: 25, price: 5 }
{ bidSide: false, volume: 100, price: 1 }
{ bidSide: false, volume: 50, price: 2}
{ bidSide: false, volume: 75, price: 8 }
最佳出價:價格25,成交量50(因為最高價格有2個訂單)最暢銷:價格1,成交量100(因為最低價格只有1個訂單)
最后,我需要考慮什么時候沒有買入或賣出訂單。 效率是高優先級,所以如果我能夠在一個首選的linq語句中這樣做。
要有效地執行此操作,您實際上只想迭代數據一次。 不幸的是,這使用LINQ實現真正的痛苦,因為還有很多工作要做。
我個人建議你不要用LINQ做這個 - 你可以用Aggregate
實現它,但它不會非常令人愉快。 雖然簡單的foreach
循環並不算太糟糕。 就像是:
int buyVolume = -1;
int sellVolume = -1;
decimal buyPrice = decimal.MinValue;
decimal sellPrice = decimal.MaxValue;
foreach (var order in orders)
{
if (order.bidSide)
{
if (order.Price > buyPrice)
{
buyPrice = order.Price;
buyVolume = order.Volume;
}
else if (order.Price == buyPrice)
{
buyVolume += order.Volume;
}
}
else
{
if (order.Price < sellPrice)
{
sellPrice = order.Price;
sellVolume = order.Volume;
}
else if (order.Price == sellPrice)
{
sellVolume += order.Volume;
}
}
}
// Check sellVolume == -1 to verify whether we've seen any sale orders
// Check buyVolume == -1 to verify whether we've seen any buy orders
// Use buyPrice/buyVolume and sellPrice/sellVolume otherwise
在LINQ中盡可能高效地執行它實際上意味着將循環中的所有邏輯放入一個函數以傳遞到Aggregate
- 並且您可能想要創建一個自定義值類型來保存四個值,以避免創建比你需要。 這可能有點矯枉過正,但你確實說過你希望它盡可能高效......
HIGHEST = orders.Max(x => x.bidSide ? x.price : (decimal?)null) ?? 0M
類似於LOWEST。
不幸的是,Linq2SQL不會將其轉換為有效的查詢。 它將在一個查詢中執行,但每次Max操作將掃描一次數據(在您的情況下,兩次:HIGHEST和LOWEST)。 在原始SQL中,您可以在一次傳遞數據時執行此操作。
這可以做LINQ明智的......
var bids = (from o in orders
where o.StockCode == "ABC" && o.BidSide == true
group o by o.Price)
.OrderByDescending(g => g.Key)
.FirstOrDefault();
var bidVolume = bids != null ? new Order { Price = bids.Key, Volume = bids.Sum(g => g.Volume) } : null;
var sells = (from o in orders
where o.StockCode == "ABC" && o.BidSide == false
group o by o.Price)
.OrderBy(g => g.Key)
.FirstOrDefault();
var sellVolume = sells != null ? new Order { Price = sells.Key, Volume = sells.Sum(g => g.Volume) } : null;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.