2016-09-27 132 views
1

我的模型包含的列表Offers。具有SpecialOffers價值true的報價應該由RGUOfferPriority訂購。 SpecialOffers價值false的報價應僅由InitialPrice(降序)訂購。OrderBy list LINQ查詢

我試過以下查詢,它實現了第一部分,即按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是連接到每個確定的報價是否是特殊與否

+0

所以,你需要2點不同的集合進行排序? – tym32167

+5

'''.Select(x => x)'''< - 無用 – tym32167

+0

集合是一樣的。 'SpecialOffer'每個報價的屬性決定它是否爲SpecialOffer –

回答

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將保持組的順序,通常你必須對外部查詢這是最後CONCAT應用ORDER BY,它轉換爲UNION ALL。那麼最簡單的辦法是使用Linq-To-ObjectsAsEnumerable

var result = specialGroup.AsEnumerable().Concat(nonSpecialGroup.AsEnumerable()).ToList(); 
+0

謝謝。這工作完美。非常好的解釋。豎起大拇指(y) –

0

你必須根據自己的類型來分割你的列表提供一個布爾值屬性,你不容爲了兩個不同用同樣的語句列表:

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

如果不是那不是SpecialOffer應該ProviderCode排序列表中的所有元素,RGUOfferPriority您可以使用此爲第二個列表:

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