我正在建立一个拍卖网站,用户可以多次竞标相同的商品(显然)。在用户的信息中心中,用户可以查看其出价。当用户多次对同一商品出价时,我只想显示出价最高的一个条目。我当前的代码显示了每个出价的条目。我尝试了一些东西,但我无法理解。这就是我所拥有的:
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);
}
}
}
如何摆脱这些循环?也许在一个链式声明中拥有它?
答案 0 :(得分:3)
到目前为止发布的评论应该是一个很好的迹象,你应该考虑重新构建这一点,但是直接的代码解决方案涉及使用System.Linq将GroupBy,Max和Select链接在一起。
答案 1 :(得分:1)
您只需创建一个用户出价词典,其中键是项目ID。然后,对于每个用户出价,如果尚未使用项目标识,则将当前出价添加到字典中,如果使用它,则查看字典中存在的项目的出价金额是否已低于当前项目然后替换字典中的现有项目与当前项目。
然而,效率非常低,因为实际上您只想加载按每个出价ID的出价金额降序排序的前1个出价,而不是加载所有出价然后计算出最高出价。如果您的用户有10,000个旧出价会怎样?他们都被装上了吗?