Linq - 如何通过三个表达式动态排序?

时间:2015-08-25 13:42:21

标签: c# linq

我想通过动态expression变量来订购结果。如果我将DateTimedouble?int更改为object,我会收到NotSupportedException。我有以下三个表达式

Expression<Func<Recipe, DateTime>> byCreatedOn = x => x.CreatedOn;
Expression<Func<Recipe, double?>> byRank = entity => entity.Comments.Any() ? entity.Comments.Average(comment => comment.Rating) : 0;
Expression<Func<Recipe, int>> byPopularity = x => x.Comments.Count();

var expression = order == 1 ? byRank : (order == 2 ? byPopularity : byCreatedOn);

以及以下查询

var list = this.DbContext.RecipeTranslations
            .Where(x => x.Language.Code == this.CurrentLanguge)
            .Where(x => string.IsNullOrEmpty(name) || x.Title.Contains(name))
            .Select(x => x.Recipe)
            .Where(x => x.IsDeleted == false)
            .Where(x => category == null || x.Categories.Any(cat => cat.Id == category))
            .OrderByDescending(expression)
            .Skip(start).Take(size).toList();

3 个答案:

答案 0 :(得分:3)

要做的一件事就是从实现中拆分出你的查询构建。

var query = this.DbContext.RecipeTranslations
            .Where(x => x.Language.Code == this.CurrentLanguge)
            .Where(x => string.IsNullOrEmpty(name) || x.Title.Contains(name))
            .Select(x => x.Recipe)
            .Where(x => x.IsDeleted == false)
            .Where(x => category == null || x.Categories.Any(cat => cat.Id == category));

if (order == 1)
{
    query = query.OrderByDescending(byRank);
}
else if (order == 2)
{
    query = query.OrderByDescending(byPopularity);
}
else
{
    query = query.OrderByDescending(byCreatedOn);
}

// Finally
var list = query.Skip(start).Take(size).toList();

答案 1 :(得分:1)

只要你的表达式评估你应该能够做到:

.OrderByDescending(expression1).ThenBy(expression2) 

等等。

答案 2 :(得分:0)

intdoubleDateTime已实施IComparable界面。

对象类型(您使用的对象类型而非intDateTimedouble)也应实现IComparable接口。

或许您可以尝试OrderByDescending方法的其他重载,这会要求比较器。