【问题标题】:Order by multiple properties with linq to sql使用 linq to sql 按多个属性排序
【发布时间】:2019-03-22 05:25:52
【问题描述】:

我有想要这样订购的清单

public class Refund {
    public int RefundStatus { get; set; }
    public DateTime SumbitTime { get; set; }
}

先按RefundStatus 订购,然后:

如果RefundStatus == 1 则按SumbitTime 升序,

如果RefundStatus != 1 则按SumbitTime 降序。

我应该如何通过 linq to sql 进行操作?

更新: 我在 Michal Turczyn 之后进行了更改。但无法翻译日志输出显示

Microsoft.EntityFrameworkCore.Query:警告:LINQ 表达式 'orderby [p].RefundStatus asc, ([p].SumbitTime.Ticks * 转换(IIF(([p].RefundStatus == 1), 1, -1), Int64)) asc, EF.Property(?[p]?, "Id") asc' 无法翻译,将 当地评价。 Microsoft.EntityFrameworkCore.Query:警告: LINQ 表达式 'orderby [p].RefundStatus asc, ([p].SumbitTime.Ticks * 转换(IIF(([p].RefundStatus == 1), 1, -1), Int64)) asc, EF.Property(?[p]?, "Id") asc' 无法翻译,将 本地评估。

【问题讨论】:

  • @vc74 抱歉,我不明白您的状态是什么意思。集合中的所有退款都有不同的退款状态
  • @Z。陈你的问题对我来说不是很清楚,一个带有样本数据的例子会有所帮助......
  • @Z.Chen 您能否提供示例输入/输出?

标签: c# linq linq-to-sql


【解决方案1】:

我会这样做:

List<Refund> refundList = new List<Refund>();
// populate your list
refundList = refundList
    // here you could also use:
    //.OrderBy(r => r.RefundStatus)
    // but I don't know if you want it this way
    .OrderBy(r => (r.RefundStatus == 1 ? 1 : -1))
    .ThenBy(r => r.SubmitTime.Ticks * (r.RefundStatus == 1 ? 1 : -1))
    .ToList();

这个想法是,当您将 -1 中的刻度数乘以 DateTime 时,它将按降序排列,而不必将您的集合分成两部分。

【讨论】:

  • 这是个好主意,但我不确定Ticks 是否可以翻译成SQL。
  • @vc74 这是由 .NET 和 Linq2Sql 框架在内部处理的。所以你不应该担心它:)
  • 并非所有 linq 查询都可以转换为 SQL,尤其是那些使用 .net 功能的查询。不过说不定也行,等OP来试试吧……
  • 这是个好主意,但它不起作用。抛出未设置为对象实例的异常对象引用。位于 D:\a\1\s\Ix.NET\Source\System 中 System.Linq.Internal.Lookup2.CreateForJoinAsync(IAsyncEnumerable1 源、Func2 keySelector, IEqualityComparer1 比较器、CancellationToken 取消令牌的 lambda_method(Closure , AnonymousObject ) 处。 Interactive.Async\Lookup.cs:301 行
  • @Z.Chen 检查NullReferenceException
【解决方案2】:

如果我正确理解您的问题,这应该可以满足您的需求。

var sorted = refundList.GroupBy(refund => refund.RefundStatus)
    .SelectMany(
        group => group.Key == 1 
        ? group.OrderBy(p => p.SumbitTime)
        : group.OrderByDescending(p => p.SumbitTime))
    .ToList();

【讨论】:

  • 对不起,它不起作用。抛出异常参数类型不匹配
【解决方案3】:

您可以使用以下内容。

var sorted = list.GroupBy(refund => refund.RefundStatus)
                 .OrderBy(x=>x.Key)
                 .SelectMany(
                             group => group.Key == 1 ? 
                             group.OrderBy(p => p.SubmitTime)
                             : group.OrderByDescending(p => p.SubmitTime));

完整示例。

        var random = new Random();
        var list = Enumerable.Range(1, 10)
            .Select(x => 
                new Refund
                {
                    RefundStatus = random.Next(0,2),
                    SubmitTime = DateTime.Now.AddMinutes(x)
                });

退款定义为

public class Refund
{
    public int RefundStatus { get; set; }
    public DateTime SubmitTime { get; set; }
}

样本输出

**排序前

Refund = 0 - SubmitTime = 22-03-2019 14:22:16
Refund = 1 - SubmitTime = 22-03-2019 14:23:16
Refund = 0 - SubmitTime = 22-03-2019 14:24:16
Refund = 0 - SubmitTime = 22-03-2019 14:25:16
Refund = 0 - SubmitTime = 22-03-2019 14:26:16
Refund = 1 - SubmitTime = 22-03-2019 14:27:16
Refund = 0 - SubmitTime = 22-03-2019 14:28:16
Refund = 1 - SubmitTime = 22-03-2019 14:29:16
Refund = 0 - SubmitTime = 22-03-2019 14:30:16
Refund = 1 - SubmitTime = 22-03-2019 14:31:16

排序后

Refund = 0 - SubmitTime = 22-03-2019 14:31:16
Refund = 0 - SubmitTime = 22-03-2019 14:29:16
Refund = 0 - SubmitTime = 22-03-2019 14:28:16
Refund = 0 - SubmitTime = 22-03-2019 14:26:16
Refund = 0 - SubmitTime = 22-03-2019 14:23:16
Refund = 1 - SubmitTime = 22-03-2019 14:22:16
Refund = 1 - SubmitTime = 22-03-2019 14:24:16
Refund = 1 - SubmitTime = 22-03-2019 14:25:16
Refund = 1 - SubmitTime = 22-03-2019 14:27:16
Refund = 1 - SubmitTime = 22-03-2019 14:30:16

【讨论】:

  • 它在linq上工作,但不能翻译成SQL
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
相关资源
最近更新 更多