c# - OrderBy().ThenBy().ThenBy() 未在实体列表上给出预期结果

标签 c# linq

无法理解为什么我的简单订购没有按预期工作。这是有问题的行:

return messages.OrderBy(o => o.MessageType)
               .ThenBy(p => p.IsUrgent)
               .ThenByDescending(p => p.Timestamp)
               .ToList();

最后两个顺序(紧急和时间戳)不能正常工作。我的结果要么按 IsUrgent 要么按时间戳排序,但绝不会同时排序。

我的最终结果应该是所有消息都按类型排序(只有 3 种类型:新建、已保存、已删除)。然后在每种类型中,先有紧急消息,然后按时间戳排序。

更新

你问了更多信息,所以在这里

[TestMethod]
    public void Messages_should_sort_correctly()
    {
        var contact = new Models.Contact(); //just to satisfy the object

        var expectedOrder = new string[] { "5", "6", "12", "3", "10", "9", "4", "8", "11", "13", "2", "7", "1" };
        var messages = new List<IMessage>
        {
            new Models.Message { FileName = "1",   MessageType = MessageType.Deleted,   Timestamp = 31,  Contact = contact },
            new Models.Message { FileName = "2",   MessageType = MessageType.Deleted,   Timestamp = 34,  Contact = contact },
            new Models.Message { FileName = "3",   MessageType = MessageType.Inbox,     Timestamp = 11,  Contact = contact },
            new Models.Message { FileName = "4",   MessageType = MessageType.Saved,     Timestamp = 25,  Contact = contact },
            new Models.Message { FileName = "5",   MessageType = MessageType.Inbox,     Timestamp = 14,  Contact = contact, IsUrgent = true },
            new Models.Message { FileName = "6",   MessageType = MessageType.Inbox,     Timestamp = 13,  Contact = contact, IsUrgent = true },
            new Models.Message { FileName = "7",   MessageType = MessageType.Deleted,   Timestamp = 32,  Contact = contact },
            new Models.Message { FileName = "8",   MessageType = MessageType.Saved,     Timestamp = 22,  Contact = contact },
            new Models.Message { FileName = "9",   MessageType = MessageType.Saved,     Timestamp = 23,  Contact = contact, IsUrgent = true },
            new Models.Message { FileName = "10",  MessageType = MessageType.Saved,     Timestamp = 24,  Contact = contact, IsUrgent = true },
            new Models.Message { FileName = "11",  MessageType = MessageType.Saved,     Timestamp = 21,  Contact = contact },
            new Models.Message { FileName = "12",  MessageType = MessageType.Inbox,     Timestamp = 12,  Contact = contact },
            new Models.Message { FileName = "13",  MessageType = MessageType.Deleted,   Timestamp = 33,  Contact = contact, IsUrgent = true }
        };

        messageServiceMock.Setup(m => m.GetAllMessagesAsync()).Returns(Task.FromResult(messages as IList<IMessage>)).AtMostOnce();

        var result = service.Messages; //this property returns the messages from our mock, and then sorts and orders
        var actualOrder = result.Select(m => m.FileName);


        //expected order "5", "6", "12", "3", "10", "9", "4", "8", "11", "13", "2", "7", "1"
        //actual order   "12", "3", "5", "6", "4", "8", "11", "10", "9", "2", "7", "1", "13" 
        Assert.IsTrue(actualOrder.SequenceEqual(expectedOrder));
    }

这就是所有魔法/困惑发生的地方

private List<Domain.Interfaces.IMessage> messages = new List<Domain.Interfaces.IMessage>();
    public IList<Domain.Interfaces.IMessage> Messages
    {
        get
        {
            if (!messages.Any())
            {
                messages = messageService.GetAllMessagesAsync().Result.ToDomain().ToList();
            }

            return messages.OrderBy(o => o.MessageType).ThenBy(p => p.IsUrgent == true).ThenByDescending(p => p.Timestamp).ToList();
        }
    }

最佳答案

理论上它应该按预期工作。您可以使用以下方式跟踪您的查询:

IQueryable<Message> query = messages
                           .OrderBy(o => o.MessageType)
                           .ThenBy(p => p.IsUrgent)
                           .ThenByDescending(p => p.Timestamp);
//debug query.ToString() to see the generated sql
//should be SELECT XXX WHERE YYY ORDER BY MessageType, IsUrgent, Timestamp DESC
return query.ToList();

关于c# - OrderBy().ThenBy().ThenBy() 未在实体列表上给出预期结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35690709/

相关文章:

c# - 如何加入 2 个列表,其中一个列表包含 2 个元素?

c# - 通过 Entity Framework 6 中另一个表中的外键获取记录

c# - Entity Framework 核心 - 包含区分大小写还是不区分大小写?

c# - 在unity3D中,点击=触摸?

c# - 创建具有多个 OR 和 AND 条件的 LINQ 表达式树

c# - 如何用 lambda 表达式连接 3 个表?

c# - UDP通信快速填满内存

c# - Uri.TryCreate 对任何字符串值返回 true?

c# - 无法添加对我的项目的引用 - 它根本没有检测到它

c# - ASP.Net 和 GetType()