so this is my query
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();
Then i have a model which has a boolean value for SortTrack
, SortCategory
and SortSkills
. I want to OrderBy Ascending if the value of the boolean is true and Descending if false.
How to achieve that?
Linq statements are composable so you can add the appropriate orderby to the query before calling tolist.
var query = list.Where(...)
if (condition)
query = query.OrderBy(...)
else
query = query.OrderByDescending(...)
return query.ToList();
In lambda it can be done like this:
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();
Else you need to use expressions like this:
var x = widgets.Where(w => w.Name.Contains("xyz"));
if (flag) {
x = x.OrderBy(w => w.property);
} else {
x = x.OrderByDescending(w => w.property);
}
Here are a few other options more in the LINQ spirit. EF won't be able to translate them to SQL, so you'll need to run these in-memory (post-AsEnumerable/ToArray/ToList) but it looks like it won't be a problem.
Take this as a simple example:
var numbers = new int[] { 5, 1, 2, 3, 44 };
Option 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);
}
}
Usage
var asc = true; // or false
var sorted = numbers.OrderByAdaptive(x => x, asc);
Option 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);
}
}
Usage
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);
Option 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);
}
}
Usage
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);
Production-wise, I would probably create a SortDirection
enum with Ascending
and Descending
values rather than a bool named asc
, but I'm silly like that.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.