【问题标题】:Linq To Sql - Dynamic OrderBy - Case WhenLinq To Sql - 动态 OrderBy - 案例何时
【发布时间】:2011-01-02 01:28:38
【问题描述】:

我正在使用 Linq to sqlLinq Dynamic OrderBy。

我知道 linq dynamic 可以进行简单的排序,例如 - orderby("column_name")。

但是它是否支持更复杂的查询,例如带有“CASE WHEN”的查询?

string orderbyQuery = "(CASE WHEN (username == 100) THEN 1 ELSE 0 END) DESC)";

这是我的查询:

var u = from u in db.users
        orderby(orderbyQuery)
        select u;

上面的例子不起作用! ,如果可能的话,有什么想法吗? 还有其他方法吗?

谢谢

【问题讨论】:

    标签: linq linq-to-sql dynamic sql-order-by


    【解决方案1】:
    var u = from u in db.users
            orderby u.username == 100 ? 1 : 0 descending
            select u;
    

    【讨论】:

    • 我必须使用动态查询,因为我有一个 int[] realUsers = 100, 22, 77, 12 等...我想根据该 int[] 对 Users 表进行排序,这意味着首先显示“realUsers”中的用户。
    • 你可以替换那个 u.username == 100 吗? 1 : 0 与(几乎)任何你想要的排序逻辑,你基本上只是用 C# 而不是 Sql 编写它。在不确切知道您尝试如何订购的情况下,很难给出比转换原始代码更好的示例...
    【解决方案2】:

    这真的很适合我:

    var queryResult = 
       from o in Source
       orderby (o.ColumnThatSaysOrderByColumn1 ? o.Column1 : o.Column2) descending
       select o
    

    希望这会有所帮助!

    【讨论】:

      【解决方案3】:
      public class Cat 
      {
           public string Name {get;set;}
           public Cat(string name) { Name = name; }
      }    
      
      var cats = new List<Cat> { new Cat("cat1"), new Cat("cat2"), new Cat("cat3") };
      var customSortExpression = new List<string> { "cat2", "cat1", "cat3" }.CustomSortOrder<Cat>("Name");
      
      //custom sort order, works with EF too //orders cat2,cat1,cat3               
      var customOrderCats = cats.AsQueryable().OrderBy(customSortExpression);
      

      与 EF 一起使用时,会生成如下所示的 sql

      SELECT [c].[Name]
         FROM [Cats] AS [c]
         ORDER BY CASE
             WHEN [c].[Name] = N'cat2'
             THEN 0 ELSE CASE
                 WHEN [c].[Name] = N'cat1'
                 THEN 1 ELSE CASE
                     WHEN [c].[Name] = N'cat3'
                     THEN 2 ELSE 3
                 END
             END
          END
      

      这是我的扩展方法CustomSortOrder&lt;TEntity&gt;

      public static Expression<Func<TEntity, int>> CustomSortOrder<TEntity>(this IList<string> customSortOrderValues, string propName) {
      
      var e = Expression.Parameter(typeof(TEntity), "e");
      var prop = typeof(TEntity).GetProperty(propName, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
      var eDotProp = Expression.MakeMemberAccess(e, prop);
      var maxLen = customSortOrderValues.Count;
      
      Expression ElseExpression(IList<string> values) {
          var value = values[0];
          var condition = Expression.Equal(eDotProp, Expression.Constant(value));
          var ifTrue = Expression.Constant(maxLen - values.Count);
          Expression ifFalse ;
      
          if (values.Count == 1) {
              ifFalse = Expression.Constant(maxLen - values.Count + 1);
          }
          else {
              values.RemoveAt(0);
              ifFalse = ElseExpression(values);
          }
          return Expression.Condition(condition, ifTrue, ifFalse);
      }
      
      return Expression.Lambda<Func<TEntity, int>>(
          ElseExpression(customSortOrderValues),
              e);
      }
      

      【讨论】:

      • 有没有办法让 linq to sql 创建一个单一的 CASE 语句,而不是很多这样的嵌套语句?我有一个大的 case 语句,当嵌套时,它超出了嵌套限制,因此 sql 失败。或者这只是 linq 中的一个错误,没有解决方法?
      • 如果案例数量非常多,我认为您不应该这样做。当您想将来自其他来源而非表格来源的订单和非常有限的 caess 数量结合起来时,这是一种权宜之计。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-31
      • 1970-01-01
      • 2011-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多