2017-01-10 3 views
2

это мой запросC# LinQ Условный OrderBy

var results = tcs.Skip(searchModel.PageSize * (searchModel.Page - 1)) 
       .Take(searchModel.PageSize) 
       .AsEnumerable() 
       .Select(x => new 
       { 
        trackId = x.TrackId, 
        trackName = x.TrackName, 
        category = _weCategoryService.FindAll().Where(y => y.WorkExperience_Track.TrackId == x.TrackId) 
         .Select(y => new { 
          categoryId = y.CategoryId, 
          categoryName = y.CategoryName, 
          skill = _skillsService.FindAll().Where(z => z.CategoryId == y.CategoryId) 
           .Select(z => new { 
            skillId = z.SkillId, 
            skillName = z.SkillName 
           }).OrderBy(z => z.skillName).ToList() 
         }).OrderBy(y => y.categoryName).ToList() 
       }).OrderBy(x => x.trackName).ToList(); 

Тогда у меня есть модель, которая имеет логическое значение для SortTrack, SortCategory и SortSkills. Я хочу OrderBy Восходящий, если значение логического значения true и Descending, если false.

Как достичь этого?

+0

Не устанавливайте линию. Трудно читать. –

+0

@ TânNguyễn Я не знаю, как встраивать запрос linq, и я также так понимаю, как я делаю свой код, поэтому мне его легче читать: D –

ответ

1

В лямбда это можно сделать так:

var results = tcs.Skip(searchModel.PageSize * (searchModel.Page - 1)) 
        .Take(searchModel.PageSize) 
        .AsEnumerable() 
        .Select(x => new 
        { 
         trackId = x.TrackId, 
         trackName = x.TrackName, 
         category = _weCategoryService.FindAll().Where(y => y.WorkExperience_Track.TrackId == x.TrackId) 
          .Select(y => new { 
           categoryId = y.CategoryId, 
           categoryName = y.CategoryName, 
           skill = _skillsService.FindAll().Where(z => z.CategoryId == y.CategoryId) 
            .Select(z => new { 
             skillId = z.SkillId, 
             skillName = z.SkillName 
            }).OrderBy(z => SortSkills ? z.skillName : "").OrderByDescending(z => !SortSkills ? z.skillName : "").ToList() 
          }).OrderBy(y => SortCategory ? y.categoryName : "").OrderByDescending(y => !SortCategory ? y.categoryName : "").ToList() 
        }).OrderBy(x => SortTrack ? x.trackName : "").OrderByDescending(x => !SortTrack ? x.trackName : "").ToList(); 

Иначе вы должны использовать такие выражения, как это:

var x = widgets.Where(w => w.Name.Contains("xyz")); 
if (flag) { 
    x = x.OrderBy(w => w.property); 
} else { 
    x = x.OrderByDescending(w => w.property); 
} 
+0

спасибо вам большое. первый ответ работает –

+0

Does OrderBy ("") все еще перебирает весь список? –

+0

@RabidPenguin Я думаю, нет. Это будет равнозначно OrderBy (x => ""), поэтому здесь мы не реализуем этот порядок на любом столбце, который он не будет перебирать. –

1

Операторы Linq являются составными, поэтому вы можете добавить соответствующий запрос к запросу перед вызовом списка.

var query = list.Where(...) 
if (condition) 
    query = query.OrderBy(...) 
else 
    query = query.OrderByDescending(...) 

return query.ToList(); 
+0

Можете ли вы изменить мой код, используя это? потому что я так пробовал, но получил проблему в 3-м объекте, который не может найти id –

0

Вот несколько других вариантов больше в LINQ дух , EF не сможет перевести их на SQL, поэтому вам нужно будет запустить их в памяти (post-AsEnumerable/ToArray/ToList), но похоже, что это не будет проблемой.

Возьмите это в качестве простого примера:

var numbers = new int[] { 5, 1, 2, 3, 44 }; 

Вариант 1

public static class EnumerableExtensions 
{ 
    public static IOrderedEnumerable<T> OrderByAdaptive<T, TKey>(
     this IEnumerable<T> enumr, 
     Func<T, TKey> selector, 
     bool ascending 
    ) 
    { 
     return ascending 
      ? enumr.OrderBy(selector) 
      : enumr.OrderByDescending(selector); 
    } 

    public static IOrderedEnumerable<T> OrderByAdaptive<T, TKey>(
     this IEnumerable<T> enumr, 
     Func<T, TKey> selector, 
     IComparer<TKey> comparer, 
     bool ascending 
    ) 
    { 
     return ascending 
      ? enumr.OrderBy(selector, comparer) 
      : enumr.OrderByDescending(selector, comparer); 
    } 
} 

Использование

var asc = true; // or false 
var sorted = numbers.OrderByAdaptive(x => x, asc); 

Вариант 2

public class LambdaComparer<T> : IComparer<T> 
{ 
    private Func<T, T, int> _cmp; 

    public LambdaComparer(Func<T, T, int> cmp) 
    { 
     _cmp = cmp; 
    } 

    public int Compare(T x, T y) 
    { 
     return _cmp(x, y); 
    } 
} 

Использование

var ascComparer = new LambdaComparer<int>((x, y) => { 
    if (x > y) return 1; 
    else if (x < y) return -1; 
    else return 0; 
}); 

var descComparer = new LambdaComparer<int>((x, y) => { 
    if (x > y) return -1; // Note the sign change 
    else if (x < y) return 1; // Note the sign change 
    else return 0; 
}); 

var asc = true; // or false 

var sorted = numbers.OrderBy(x => x, asc ? ascComparer : descComparer); 

Вариант 3

public class ReverseComparer<T> : IComparer<T> where T : IComparable<T> 
{ 
    private IComparer<T> _nonReversed; 

    public ReverseComparer() 
    { 
     _nonReversed = Comparer<T>.Default; 
    } 

    public ReverseComparer(IComparer<T> nonReversed) 
    { 
     _nonReversed = nonReversed; 
    } 

    public int Compare(T obj1, T obj2) 
    { 
     return -1 * _nonReversed.Compare(obj1, obj2); 
    } 
} 

Использование

var ascComparer = Comparer<int>.Default; 
var descComparer = new ReverseComparer<int>(); // or new ReverseComparer<int>(ascComparer); 

var asc = true; // or false 

var sorted = numbers.OrderBy(x => x, asc ? ascComparer : descComparer); 

По-видимому, я создал бы SortDirection enum с Ascending и Descending значениями, а не bool с именем asc, но я так глуп.