Linq中的动态订单

She*_*riy 5 c# linq

我有一个访问数据库的应用程序,必须根据输入按不同的字段排序结果.

这是我的排序功能:

IQueryable<Entity> GetSortedData(IQueryable<Entity> result, String orderby, bool desc)
{
   switch (orderby.ToLower())
   {
     case "id":
       result = result.OrderBy(c => c.Id);
       break;

     case "code":
       result = result.OrderBy(c => c.Code);
       break;

     case "active":
       result = result.OrderBy(c => c.Active);
       break;

     default:
       result = result.OrderBy(c => c.Name);
       break;
   }

   if (pageData.SortDesc)
   {
     var res = result.ToList();
     res.Reverse();
     return res.AsQueryable();
   }

   return result;      
}
Run Code Online (Sandbox Code Playgroud)

这段代码存在一些我不喜欢的问题:

  1. 重复的代码太多了.如果它是"纯粹的SQL"查询,它看起来像

    SELECT*FROM data_table ORDER BY CASE @OrderBy WHEN'id'Then id when'code'THEN code WHEN'active'THEN
    active ELSE name
    END;

  2. 转换为列表并返回以进行反转.我不能改变返回值类型,我绝对不想写更无用的代码(基本上是翻倍switch caseOrderByDescending).

任何人都可以建议使这个功能更好看的方法,最好仍然使用LINQ

Jon*_*eet 11

嗯,你肯定想用OrderByDescending而不是倒车.它不会像SQL一样简短,但你至少可以使用:

IQueryable<Entity> GetSortedData(IQueryable<Entity> result, String orderby, bool desc)
{
   switch (orderby.ToLowerInvariant())
   {
     case "id":
         return desc ? result.OrderByDescending(c => c.Id) : result.OrderBy(c => c.Id);
     case "code":
         return desc ? result.OrderByDescending(c => c.Code) : result.OrderBy(c => c.Code);
     case "active":
         return desc ? result.OrderByDescending(c => c.Active) : result.OrderBy(c => c.Active);
     default:
         return desc ? result.OrderByDescending(c => c.Name) : result.OrderBy(c => c.Name);
   }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用自己的扩展方法删除重复:

public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(
    this IQueryable<TSource> source,
    Expression<Func<TSource,?TKey>> keySelector,
    bool descending) =>
    descending ? source.OrderByDescending(keySelector) : source.OrderBy(keySelector);
Run Code Online (Sandbox Code Playgroud)

然后写:

IQueryable<Entity> GetSortedData(IQueryable<Entity> result, String orderby, bool desc)
{
   switch (orderby.ToLowerInvariant())
   {
     case "id": return result.OrderBy(c => c.Id, desc);
     case "code": return result.OrderBy(c => c.Code, desc);
     case "active": return result.OrderBy(c => c.Active, desc);
     default: return result.OrderBy(c => c.Name, desc);
   }
}
Run Code Online (Sandbox Code Playgroud)