【问题标题】:Order by multiple date columns按多个日期列排序
【发布时间】:2018-10-29 19:34:02
【问题描述】:

我在近似 linq 查询时遇到了困难,该查询按照我想要的方式按多个日期列排序。问题是我想获取表的第一行和最后一行(并为这些设置 isFirst 和 isLast 变量),按两列排序; date1 和 date2 的方式是,如果 date1 有一个值,则应该在 ORDER BY 中使用它。如果 date2 有值而 date1 没有值,则在 ORDER BY 中使用 date2。

在 T-SQL 中,我的查询如下所示:

SELECT * FROM MyDataTable 
    ORDER BY 
        CASE
        WHEN date1 IS NOT NULL
            THEN date1
        WHEN date2 IS NOT NULL AND date1 IS NULL
            THEN date2
        END
    DESC

并产生这个,这正是我想要的:

Id      date1       date2       isFirst   isLast
------------------------------------------------
1234    null        4/3/2014    False     True
1232    3/5/2014    3/7/2014    False     False
1236    8/20/2013   null        False     False
1233    null        4/5/2013    False     False
1235    12/5/2012   null        False     False
1239    9/12/2011   null        False     False
1240    8/5/2011    null        True      False

我不知道从这里去哪里,

MyDataTable.OrderByDescending(x=>x.date1).ThenByDescending(x=>x.date2)

没有给我我需要的东西,因为 date2 无论如何都会最后结束。 我尝试使用临时表,将date1=date2 设置为date1=null,按date1 排序,然后使用Id 更新原始表,但这相当草率,我不确定这样做的性能成本。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    使用HasValue? 运算符

    var query  = MyDataTable
       .OrderByDescending(x => x.date1.HasValue ? x.date1.Value : x.date2 ?? DateTime.MinValue);
    

    对于您问题的第一部分/最后一部分,如果您想用此查询填充一个集合并且在那里确定它就足够了,您可以简单地使用:

    var list = query
        .Select(x => new EntityTypeName
        { 
            ..., 
            IsFirst = false, 
            IsLast = false
        }).ToList();
    
    if(list.Count > 0)
        list[0].IsFirst = true;
    if(list.Count > 1)
        list[list.Count-1].IsLast = true;
    

    【讨论】:

    • 能否将x.date1.HasValue ? x.date1.Value : x.date2 ?? DateTime.MinValue 简化为x.date1 ?? x.date2 ?? DateTime.MinValue
    • 谢谢,这真的让我很开心!我不得不用一个额外的条件来改变这个语句,因为我在使用 datetime 时收到了关于 null-coalescing 运算符的投诉,但除此之外,完美。
    【解决方案2】:

    假设 date1 和 date2 可以为空: 您可以使用?: 运算符模拟EF 中的if else

    MyDataTable
        .OrderByDescending(x =>
                            x.date1.HasValue ?
                                x.date1 : x.date2);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-14
      相关资源
      最近更新 更多