排序方式列表 LINQ 查询

本文关键字:查询 LINQ 列表 方式 排序 | 更新日期: 2023-09-27 18:09:11

我的模型包含Offers列表。 具有SpecialOffers价值true应按RGUOfferPriority排序。价值false SpecialOffers的产品/服务应仅按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();

EDIT SpecialOffer 是附加到每个选件的布尔属性,用于确定选件是否为特别

排序方式列表 LINQ 查询

优惠

您应该首先按此属性分组,以获得两个可以单独订购的组:

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(); 

您必须根据列表的类型拆分列表,不能使用相同的语句对两个不同的列表进行排序:

var result1 = model.Offers.Where(x => x.SpecialOffer).OrderBy(x => x.InitialPrice);
var result2 = model.Offers.Except(result1).OrderBy(...);

如果不是列表中不是所有不是SpecialOffer的元素都应该按ProviderCodeRGUOfferPriority排序,则可以将其用于第二个列表:

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