我有一个包含许多不同排序顺序的枚举:
public enum LogSortOrder
{
DateTimeAsc = 1,
DateTimeDesc = 2,
LevelAsc = 3,
LevelDesc = 4,
MessageAsc = 5,
MessageDesc = 6
}
我不想在switch语句中构建我的查询,而是想知道是否有更高效或更优雅的方法来实现这一点,所以我不需要将我的查询分开并且有一个丑陋的开关块,如下所示:
var query = context.Set<Log>().AsQueryable();
switch ( sortOrder )
{
case LogSortOrder.LevelAsc:
query = query.OrderBy( l => l.Level );
break;
case LogSortOrder.LevelDesc:
query = query.OrderByDescending( l => l.Level );
break;
case LogSortOrder.MessageAsc:
query = query.OrderBy( l => l.Message );
break;
case LogSortOrder.MessageDesc:
query = query.OrderByDescending( l => l.Message );
break;
case LogSortOrder.DateTimeAsc:
query = query.OrderBy( l => l.Date );
break;
default:
query = query.OrderByDescending( l => l.Date );
break;
}
return await query
.Skip( offset )
.Take( limit )
.ToListAsync();
答案 0 :(得分:1)
好吧,您可以使用System.Linq.Expressions
构建它。我不会称之为更高效或更优雅。可能更灵活(允许轻松添加新的enum
成员),但同时更容易出错。
var query = context.Set<Log>().AsQueryable();
var sortInfo = sortOrder.ToString();
bool descending = sortInfo.EndsWith("Desc");
var propertyName = sortInfo.Substring(0, sortInfo.Length - (descending ? "Desc" : "Asc").Length);
var parameter = Expression.Parameter(typeof(Log), "log");
var selector = Expression.Lambda(Expression.PropertyOrField(parameter, propertyName), parameter);
query = query.Provider.CreateQuery<Log>(Expression.Call(
typeof(Queryable),
"OrderBy" + (descending ? "Descending" : null),
new [] { parameter.Type, selector.Body.Type},
query.Expression, Expression.Quote(selector)));
// ...
答案 1 :(得分:1)
我认为最简单,最直接的方法是保持逻辑,但将其包装在扩展方法中,以便在使用它时看起来更好。这也更容易维护。
public static class SortHelper
{
public static IOrderedQueryable<Log> SortFromCommand(this IQueryable<Log> entities, LogSortOrder sortOrder)
{
IOrderedQueryable<Log> ordered;
switch (sortOrder)
{
case LogSortOrder.LevelAsc:
ordered = entities.OrderBy(l => l.Level);
break;
case LogSortOrder.LevelDesc:
ordered = entities.OrderByDescending( l => l.Level );
break;
case LogSortOrder.MessageAsc:
ordered = entities.OrderBy( l => l.Message );
break;
case LogSortOrder.MessageDesc:
ordered = entities.OrderByDescending( l => l.Message );
break;
case LogSortOrder.DateTimeAsc:
ordered = entities.OrderBy( l => l.Date );
break;
default:
ordered = entities.OrderByDescending( l => l.Date );
break;
}
return ordered;
}
}
用法:
var sortCommand = LogSortOrder.LevelAsc;
var results = context.Set<Log>().AsQueryable()
.SortFromCommand(sortCommand)
.Skip(10)
.ToList();
答案 2 :(得分:0)
您可以使用可以将字符串转换为linq表达式的库,如下所示: https://www.nuget.org/packages/System.Linq.Dynamic.Library/
此时您可以(例如)将您的枚举值更改为字符串(即MessageAsc = "Message"
或query = query.OrderBy(sortOrder);
然后你的switch语句将缩减为:
PieChart