2016-09-27 3 views
1

Моя модель содержит Список Offers. предлагает SpecialOffers значение true должно быть заказано RGU и OfferPriority. Предложения, имеющие SpecialOffers значение false, должны быть заказаны по InitialPrice (по убыванию).Список заказов LINQ Query

Я попробовал следующий запрос: он достигает первой части, заказанной по 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(); 

EDITSpecialOffer является Логическое свойство придает каждому предложению, которое определяет, является ли предложение Специальное или не

+0

Так что, вам нужно сортировать 2 разных коллекций? – tym32167

+5

'' '.Выбрать (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 будет держать порядок групп, как правило, вы должны применить ORDER BY на внешний запрос, который является окончательной CONCAT, он переводится на UNION ALL. Тогда проще всего было бы использовать Linq-To-Objects с AsEnumerable:

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

Спасибо. Это прекрасно работает. Очень приятные объяснения. Thumbs Up (y) –

0

Вы должны разделить свои списки на основе их типа, вы не можете порядка двух различных списки с тем же утверждением:

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

Если не все элементы в списке, которые не SpecialOffer должны быть отсортированы по ProviderCode, RGU и OfferPriority вы можете использовать это для второго списка:

var result2 = mode.Offers.Where(x => !x.SpecialOffer) 
    .Where(x => x.Provider.ProviderCode.Equals(provider)) 
    .OrderByByDescending(t => t.RGU) 
    .ThenBy(p => p.OfferPriority); 
Смежные вопросы