0

I've three lists in an object and want to perform order by operation using LINQ

object containing lists

public class ApplicationCommunications
{
    public ApplicationCommunications()
    {
        listNotification = new List<ApplicationNotifications>();
        listEmail = new List<ApplicationEmail>();
        listSMS = new List<ApplicationSMS>();
    }

    public List<ApplicationNotifications> listNotification { get; set; }
    public List<ApplicationEmail> listEmail { get; set; }
    public List<ApplicationSMS> listSMS { get; set; }
}

Getting data from db

ApplicationCommunications applicationCommunications = new ApplicationCommunications();
applicationCommunications.listNotification = GetApplicationNotification(applicationId).Select(c => new ApplicationNotifications
{
    NotificationId =  c.NotificationId,
    Message = c.Message,
    SendDate = c.SendDate.Value
}).ToList();

applicationCommunications.listEmail = GetApplicationEmails(applicationId).Select(t => new ApplicationEmail
{
    EmailContent = t.Body,
    EmailAddress = t.Email,
    SendDate = t.SendDate.Value,
}).ToList();

applicationCommunications.listSMS = GetApplicationMessage(applicationId).Select(t => new ApplicationSMS
{
    SMSContent = t.Body,
    PhoneNumber = t.Phone,
    SendDate = t.SendDate.Value,
}).ToList();

We've three lists each list of the object has "senddate" property now I want to make a new list from these three lists where we will have data in order. Is that possible?

How we can perform order by with send date? simply I want to display data in order.

  • 1
    Do you see that ordering three lists is different than just ordering one? If not, you might simplify your question to come closer to the core of what you want to discover. – Dejan Mar 18 '21 at 07:57
  • 1
    Does this answer your question? [How to Sort a List by a property in the object](https://stackoverflow.com/questions/3309188/how-to-sort-a-listt-by-a-property-in-the-object) – Self Mar 18 '21 at 08:04
  • Yes, you are right I want to order by each send date property. simply I want to display data in order. @Dejan – user12577393 Mar 18 '21 at 08:05
  • @user12577393: _what_ you want to order? A single list, all three lists or something that contains instances of this `ApplicationCommunications`-class? – Tim Schmelter Mar 18 '21 at 09:23
  • @TimSchmelter pardon for the incomplete question. We've three lists each list of the object has "senddate" property now I want to make a new list from these three lists where we will have data in order. Is that possible? – user12577393 Mar 18 '21 at 09:33

3 Answers3

3

Select method gives you Enumerable type of list. Enumerable can be ordered by OrderBy, so simply do this

applicationCommunications.listNotification = GetApplicationNotification(applicationId).Select(c => new ApplicationNotifications
        {
            NotificationId =  c.NotificationId,
            Message = c.Message,
            NotificationSendDate = c.SendDate.Value
        })
        .OrderBy(an => an.NotificationSendDate)
        .ThenBy(an => an.NotificationId)
        .ToList();

EDIT: You can read more here https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.orderby?view=net-5.0

  • This will only order by listNotifications. is there any way we can compare with other lists? – user12577393 Mar 18 '21 at 08:10
  • I'm sorry, I probably don't get it quite well what you try to achieve. Every list of yours have different parameters which makes impossible to compare every list with each other. You can order every list like I did with listNotification and then you would have 3 lists ordered as you wanted. If this doesn't help, could you please provide example of data how would you like to have lists ordered? – Kęstutis Ramulionis Mar 18 '21 at 08:17
  • pardon for the incomplete question. We've three lists each list of the object has "senddate" property now I want to make a new list from these three lists where we will have data in order. Is that possible? – user12577393 Mar 18 '21 at 09:34
1

pardon for the incomplete question. We've three lists each list of the object has "senddate" property now I want to make a new list from these three lists where we will have data in order. Is that possible?

As shown in the other answer you need OrderBy:

List<DateTime> orderedSendDates = applicationCommunications.listNotification
    .Select(x => x.NotificationSendDate)
    .Concat(applicationCommunications.listEmail.Select(x => x.EmailSendDate))
    .Concat(applicationCommunications.listSMS.Select(x => x.SMSSendDate))
    .OrderBy(dt => dt)
    .ToList();

If you want unique DateTimes use Distinct before the OrderBy.

If you don't have these properties initialized when you want the list you could do:

List<DateTime> orderedSendDates = 
    GetApplicationNotification(applicationId).Select(x => x.SendDate)
    .Concat(GetApplicationEmails(applicationId).Select(x => x.SendDate))
    .Concat(GetApplicationMessage(applicationId).Select(x => x.SendDate))
    .Where(sendDateOrNull => sendDateOrNull.HasValue)
    .Select(sendDateOrNull => sendDateOrNull.Value)
    .OrderBy(dt => dt)
    .ToList();
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • Thanks, this is what I was trying to do. – user12577393 Mar 18 '21 at 10:11
  • So you get just a list of `DateTime`. How would you add some data (description, Id) to your list elements so that you retrieve the real Email, Notifications, Sms objects ? – XouDo Mar 18 '21 at 14:36
  • @XouDo: OP is just interested in the `SendDate` property which is a `Nullable` and he wants an ordered `List` of it. He wasn't clear in his requirement. Of course you lose the relation to the other information. – Tim Schmelter Mar 18 '21 at 14:42
1

If you want a big list containing the different types of elements, ordered by sendDate (but not just a list of dateTime), you may first create a common type for that :

    public class SentElement {
        public string ElementDescription {get ; set;}
        public DateTime SendDate { get; set;}
    }

Then map your different types to the common type using Select, filling the description the way you want for each type of element:

var listNotification = GetApplicationNotification(applicationId).Select(c => new SentElement
{
    ElementDescription = c.NotificationId + c.Message,
    SendDate= c.SendDate.Value
}).ToList();
    
var listEmail = GetApplicationEmails(applicationId).Select(t =>  new SentElement
{
    ElementDescription = t.EmailContent + t.EmailAddress,
    SendDate = t.SendDate.Value,
}).ToList();
    
var listSMS = GetApplicationMessage(applicationId).Select(t => new SentElement
{
    ElementDescription = t.Body + t.Phone,
    SendDate = t.SendDate.Value,
}).ToList();

And finally merging and ordering the result :

  var mergedList = listNotification.Concat(listEmail).Concat(listSMS).OrderByDescending(t=> t.SendDate);
XouDo
  • 945
  • 10
  • 19