OrderBy列出LINQ查询

时间:2016-09-27 09:53:04

标签: c# linq

我的模型包含Offers的列表。价值SpecialOffers true的商品应由RGUOfferPriority订购。 SpecialOffersfalse的优惠只能按InitialPrice(降序)排序。

我尝试了以下查询,它实现了第一部分,即由RGUOfferPriority排序,但这也适用于非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是附加到每个商品的布尔属性,用于确定商品是否为特价商品

2 个答案:

答案 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-ObjectsAsEnumerable一起使用:

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的所有元素都不应按ProviderCodeRGUOfferPriority排序,您可以将其用于第二个列表:< / p>

var result2 = mode.Offers.Where(x => !x.SpecialOffer)
    .Where(x => x.Provider.ProviderCode.Equals(provider))
    .OrderByByDescending(t => t.RGU)
    .ThenBy(p => p.OfferPriority);