Having trouble understanding why my simple ordering doesn't work as expected. Here's the offending line:
return messages.OrderBy(o => o.MessageType)
.ThenBy(p => p.IsUrgent)
.ThenByDescending(p => p.Timestamp)
.ToList();
The last two orderings (Urgent and Timestamp) don't work correctly. My results are either ordered by IsUrgent or Timestamp, but never both.
My end result should be all messages are sorted by type (there's only 3 types New, Saved, Deleted). Then in each type, have urgent messages first, and then order by the timestamp.
UPDATE
You asked for more info, so here it is
[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));
}
And here is where all the magic/confusion happens
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();
}
}
Theoretically it should work as expected. You can trace your query using:
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With