问题描述
|
我正在建立一个拍卖网站,用户可以对同一项目进行多次投标(显然)。在用户的仪表板中,用户可以查看其出价。当用户对同一项目多次出价时,我只希望显示一个具有最高出价值的条目。我当前的代码显示每个出价的条目。我尝试了一些尝试,但无法解决。这是我所拥有的:
public class Bid
{
public int Id { get; set; }
public double Amount { get; set; }
public DateTime Date { get; set; }
public virtual Item Item { get; set; }
public virtual User User { get; set; }
}
protected override List<ItemForUserBids> ResolveCore(User source)
{
var items = new List<ItemForUserBids>();
var userBids = source.Bids;
foreach (var bid in userBids)
{
var item = bid.Item;
var c = new ItemForUserBids
{
BidValue = bid.Amount,BidId = bid.Id,Description = item.Description,Id = item.Id,ItemThumb = item.MainImageLink(),Status = _itemsService.GetBiddingStatus(item,source),TimeLeft = item.EndDate.TimeLeft(),Title = item.Title
};
items.Add(c);
}
return items;
}
我试图根据Item.Id来获得不同的出价,但这没有用。现在,我正在考虑也许可以通过某种方式使用Bid实体的Date属性来获得所需的结果,但是我的头不再思考。
有什么建议么?
更新:
我像使用许多建议的那样使用字典并使用OrderBy()和Max()来使其工作。但是我认为后者可以进一步改善。
使用字典的实现(有效):
var userBids = new Dictionary<string,Bid>();
foreach (var bid in allUserBids)
{
var key = bid.Item.Id.ToString();
if(userBids.ContainsKey(key))
{
if (userBids[key].Amount < bid.Amount)
userBids[key] = bid;
}
userBids[key] = bid;
}
尝试使用其他方法(有效):
var highestBids =
source.Bids.Where(x => x.Date > DateTime.Now.AddYears(-1))
.GroupBy(x => x.Item.Id,(itemId,bids) =>
new
{
ItemId = itemId,MaxBid = bids.Max(x => x.Amount)
}).ToList();
var userBids = new List<Bid>();
foreach (var bid in source.Bids)
{
for(var i = 0; i < highestBids.Count; i++)
{
var curr = highestBids[i];
if (bid.Item.Id.Equals(curr.ItemId) && bid.Amount.Equals(curr.MaxBid)) {
userBids.Add(bid);
highestBids.Remove(curr);
}
}
}
我如何摆脱这些循环?也许所有这些都在一个链接的语句中?
解决方法
到目前为止发表的评论应该很好地表明您应该考虑对其进行重新架构,但是直接的代码解决方案包括使用System.Linq将GroupBy,Max和Select链接在一起。
, 您可以简单地创建一个用户出价字典,其中的关键是商品ID。然后,对于每个用户出价(如果尚未使用项目ID),则将当前出价添加到字典中(如果已使用),然后查看字典中已存在的项目的出价金额是否低于当前项目,然后替换词典中现有的项目与当前项目。
但是,这效率很低,因为实际上您只想加载每个出价ID的按出价金额降序排列的前1个出价,而不是加载所有出价然后算出最高出价。如果您的用户有10,000个旧出价,该怎么办?他们都被加载了吗?