我的模型包含Offers
的列表。价值SpecialOffers
true
的商品应由RGU
和OfferPriority
订购。 SpecialOffers
值false
的优惠只能按InitialPrice
(降序)排序。
我尝试了以下查询,它实现了第一部分,即由RGU
和OfferPriority
排序,但这也适用于非SpecialOffers
。
实现这两项任务的查询应该是什么?
List<OfferModel> providerOffers = Model.Offers
.Where(x => x.Provider.ProviderCode.Equals(provider))
.OrderByDescending(o => o.SpecialOffer)
.ThenByDescending(t => t.RGU)
.ThenBy(p => p.OfferPriority)
.Select(x => x)
.ToList();
编辑 SpecialOffer
是附加到每个商品的布尔属性,用于确定商品是否为特价商品
答案 0 :(得分:3)
您应首先按此属性进行分组,以获得两个可以单独订购的组:
var offers = Model.Offers.Where(o => o.Provider.ProviderCode.Equals(provider));
var offerGroups = offers.GroupBy(o => o.SpecialOffer);
var specialGroup = offerGroups.Where(g => g.Key == true)
.SelectMany(g => g)
.OrderByDescending(o => o.InitialPrice);
var nonSpecialGroup = offerGroups.Where(g => g.Key == false)
.SelectMany(g => g)
.OrderByDescending(t => t.RGU)
.ThenBy(p => p.OfferPriority);
var result = specialGroup.Concat(nonSpecialGroup).ToList();
由于LINQ的延迟执行,这些查询将作为单个sql查询执行。
免责声明:我不确定生成的sql是否会保留组的顺序,通常你必须在外部查询上应用ORDER BY
,这是最终的CONCAT
,它被翻译为一个UNION ALL
。最简单的方法是将Linq-To-Objects
与AsEnumerable
一起使用:
var result = specialGroup.AsEnumerable().Concat(nonSpecialGroup.AsEnumerable()).ToList();
答案 1 :(得分:0)
您必须根据类型拆分列表,不能使用相同的语句订购两个不同的列表:
var result1 = model.Offers.Where(x => x.SpecialOffer).OrderBy(x => x.InitialPrice);
var result2 = model.Offers.Except(result1).OrderBy(...);
如果列表中不是SpecialOffer
的所有元素都不应按ProviderCode
,RGU
和OfferPriority
排序,您可以将其用于第二个列表:< / p>
var result2 = mode.Offers.Where(x => !x.SpecialOffer)
.Where(x => x.Provider.ProviderCode.Equals(provider))
.OrderByByDescending(t => t.RGU)
.ThenBy(p => p.OfferPriority);