XamDev
XamDev

Reputation: 3647

Conditional order by in linq

I have ViewModel as follows

public class LMS_ClassDiscussionListViewModel
{
    public  int ReplyCount { get; set; }
    public LMS_ClassDiscussion ClassDiscussion { get; set; }
}

and the model LMS_ClassDiscussion which is referred in above view model is as follows

public partial class LMS_ClassDiscussion
{
    [Key]
    public int ClassDiscussionID { get; set; }
    public int? ParentClassDiscussionID { get; set; }
    public int MessageTypeID { get; set; }
    public int ClassID { get; set; }
    public int DiscussionUserID { get; set; }
    public int NotificationStatusID { get; set; }
    public string Discussion { get; set; }
    public DateTime DiscussionDate { get; set; }
    public bool IsPrivate { get; set; }
    public bool IsRead { get; set; }
    public string DiscussionTitle { get; set; }
}

I am getting the records in list as follows

List<LMS_ClassDiscussionListViewModel> modelList = GetData();

So, this list I want to sort based on NotificationStatusID = 2.

Means, those records which has NotificationStatusID as 2 it should come first and rest after that.

So, for this I have tried in below way but the list is not getting sorted

modelList = modelList.OrderBy(x => x.ClassDiscussion.NotificationStatusID)
                     .ThenBy(x => x.ClassDiscussion.NotificationStatusID == 2)
                     .ToList();

How can i sort this list with NotificationStatusID = 2 ?

Thanks !

Upvotes: 0

Views: 1566

Answers (3)

moarboilerplate
moarboilerplate

Reputation: 1643

Assuming you have no negatives, you can just do an .OrderBy(m => m.ClassDiscussion.NotificationStatusID == 2 ? -1 : m.ClassDiscussion.NotificationStatusID). This way you only have to traverse the list once.

Upvotes: 2

Sefe
Sefe

Reputation: 14007

What you are doing is to sort by NotificationStatusID as the main sort criterion, which will put everything in order. Then within that order, you order by NotificationStatusID == 2.

What you can do is to write a comparer that implements IComparer<int> and that puts all elements with a value of 2 on top of the list. Then you can use this comparer in SortBy (there is an overload for that).

If you want to save yourself the comparer, try this:

modelList = modelList.OrderBy(x => x.ClassDiscussion.NotificationStatusID == 2 ? Int32.MinValue : x.ClassDiscussion.NotificationStatusID)

That will treat all elements with a value of 2 as Int32.MinValue, which will move them right on top.

Upvotes: 2

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37020

You may first select your elements with Id = 2 and then concatenate the rest at the end using Enumerable.Concat:

var result = modelList.Where(x => x.ClassDiscussion.NotificationStatusID == 2)
        .Concat(modeList.Where(x => x.ClassDiscussion.NotificationStatusID != 2));

Upvotes: 2

Related Questions