【问题标题】:linq order by based on multiple columns and various crietrialinq order by 基于多列和各种标准
【发布时间】:2021-11-05 09:19:27
【问题描述】:

我在 sql 中有按此顺序排列的数据。

现在,我想使用 QuestionDataTypeIdDisplayOrder 订购此列表,但最后希望此 QuestionDataTypeId = 0。所以最终的结果将是第一行 = 6 然后 7 然后 8 然后 1 到 5。

我想用 C# 和 linq 来实现。

到目前为止我尝试了什么?

这是我的代码,但它不起作用。

var data = entity
    .OrderByDescending(m => m.QuestionDataTypeId == 0)
    .ThenBy(m => m.QuestionDataTypeId)
    .ThenBy(m => m.DisplayOrder);

我已经通过合并 2 个不同的变量来解决这个问题,这些变量分别为 QuestionDataTypeId = 0 和所有其他 QuestionDataTypeId 排序,但只是想知道在单行中对于这种情况什么是正确的 linq。

任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 对我来说似乎是一个很好的解决方案。这里建议的类似方法:stackoverflow.com/questions/15023226/…
  • 是的,看起来不错,但希望在 linq 中使用这个
  • 最终你的 LINQ 将被转换成 SQL,除非你做你的排序客户端,如果可能的话应该避免。
  • 同意,但存储在 db 中的数据排列不正确。所以在检索数据时,我必须以这种方式排序。
  • 我认为您的第一个排序应该是 OrderBy 而不是 OrderByDescending。试试看:.OrderBy(m => m.QuestionDataTypeId == 0)

标签: c# linq sorting


【解决方案1】:

尝试替换 QuestionDataTypeId where value = 0

.OrderBy(x=>x.QuestionDataTypeId==0?int.MaxValue:x.QuestionDataTypeId)
.ThenBy(t=>t.DisplayOrder)

【讨论】:

  • 我不明白简单地使用.OrderBy(m => m.QuestionDataTypeId == 0) 有什么问题。可惜这个建议没有得到回应。
  • 我的猜测是使用布尔比较只会产生两个值。整数值产生一个用于序数比较的集合。
【解决方案2】:

您可以为 OrderBy 编写自己的比较器

示例数据结构:

public record Table
{
    public Table(int qdtId, int displayOrder, string text)
    {
        QuestionDataTypeId = qdtId;
        DisplayOrder = displayOrder;
        Text = text;
    }

    public int QuestionDataTypeId {  get; set; }
    public int DisplayOrder {  get; set; }
    public string Text { get; set; }
}

public class TableComparer : IComparer<Table>
{
    public int Compare(Table? x, Table? y)
    {
        if(x.QuestionDataTypeId!= 0 && y.QuestionDataTypeId!=0 || x.QuestionDataTypeId == 0 && y.QuestionDataTypeId == 0)
        {
            return y.QuestionDataTypeId.CompareTo(x.QuestionDataTypeId);
        }
        return x.QuestionDataTypeId == 0 && y.QuestionDataTypeId != 0 ? int.MinValue : int.MaxValue;
    }
}

然后在代码中:

List<StringConcatBug.Table> list = new()
{
    new(0, 1, "Comfortable"),
    new(0, 2,"attainable"),
    new(0, 3,"recent goal"),
    new(0, 4,"comfortable"),
    new(2, 2,"Last Name"),
    new(3, 3,"Email"),
    new(0, 5, "feeling"),
    new(1, 1, "First Name"),

};

var ordered = list.OrderByDescending(t=>t,new TableComparer());

foreach(var v in ordered) {  Console.WriteLine(v);}

输出

Table { QuestionDataTypeId = 1, DisplayOrder = 1, Text = First Name }
Table { QuestionDataTypeId = 2, DisplayOrder = 2, Text = Last Name }
Table { QuestionDataTypeId = 3, DisplayOrder = 3, Text = Email }
Table { QuestionDataTypeId = 0, DisplayOrder = 1, Text = Comfortable }
Table { QuestionDataTypeId = 0, DisplayOrder = 2, Text = attainable }
Table { QuestionDataTypeId = 0, DisplayOrder = 3, Text = recent goal }
Table { QuestionDataTypeId = 0, DisplayOrder = 4, Text = comfortable }
Table { QuestionDataTypeId = 0, DisplayOrder = 5, Text = feeling }

【讨论】:

    【解决方案3】:

    我通常使用这个算法

    
    var mult=100000; // You can select a different number depending how many records of 
                     //  the same type  you expecting; Numbers should not overlap
    
    var data = entity
        .OrderBy(m => (m.QuestionDataTypeId*mult + m.DisplayOrder))
        .....
    

    【讨论】:

      猜你喜欢
      • 2011-06-28
      • 1970-01-01
      • 2017-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多