Home > other >  How to order items in a list of dictionaries
How to order items in a list of dictionaries

Time:02-21

I Would like to return children and grandchildren records(i.e. itemNo) in the order they are updated to database. Below query sorts record by itemNo ASC (by default). I believe sorting by Timestamp, will return records in the same order they are updated.

I tried adding Timestamp as below but doesn't work as expected.

Query to return children and grandChildren:

public async Task<List<Child>> GetChild(string parentItemNo)
{
           return await DbContext.Items
                .Where(x => x.ItemNo== parentItemNo)
                .SelectMany(x => x.Children.OrderByDescending(t => t.Timestamp).Select(c => new Child
                    {
                        ItemNo = c.ItemNo,
                        ItemName = c.ItemName,  
                        Timestamp = c.Timestamp,
                        GrandChildItemNos = c.Children.OrderByDescending(t => t.Timestamp).Select(gc => 
                           new GrandChild 
                           { 
                              ItemNo = gc.ItemNo, 
                              ItemName = gc.ItemName,
                              Timestamp = gc.Timestamp,
                           })  
                    })).ToListAsync();       // may i know how iadd orderBy here
 }

Below is how my responseData look:

[
    {"itemNo":"1111","itemName":"A1111", "timestamp":"AAAAAoc5I/o=", "grandChildSerialNos":[]}, 
    {"itemNo":"2222","itemName":"B2222"," "timestamp":"AAAAAoc5I/s=", "grandChildSerialNos":[]},
    {"itemNo":"3333","itemName":"C3333", "timestamp":"AAAAAoc5I/0=", "grandChildSerialNos": 
         [
             {"itemNo":"1234","itemName":"CH1234"..}, 
             {"itemNo":"5678","itemName":"CH5678"...}
         ]
    },      
    {"itemNo":"4444","itemName":"D4444", "timestamp":"AAAAAoc5I/4=" "grandChildSerialNos":[]}
   {"itemNo":"5555","itemName":"E5555", "timestamp":"AAAAAoc5I/w=" "grandChildSerialNos":[]}
]

I want responseData to return ItemNo "5555" before "3333" & "4444" (as "5555" was updated before 3333 & 4444). But response is not returned in that order. I want 'ItemNo' to be sorted by 'Timestamp' instead of ascending order.

Model class as below:

public partial class Item
{
    public byte[] Timestamp { get; set; }
    public string itemNo { get; set; }  
    public string itemName { get; set; } 
}

public class GrandChild
{
    public string ItemNo {get;set;}
    public string ItemName {get;set;}
    public byte[] Timestamp { get; set; }
}

public class Child
{
    public string ItemNo {get;set;}
    public string ItemName {get;set;}   
    public byte[] Timestamp { get; set; }
    public IEnumerable<GrandChild> GrandChildItemNos {get;set;}
}

I do not need Timestamp in the responseData. Timestamp is needed only to order the itemNos (in the same order they are added or updated). Thank you.

CodePudding user response:

Add .OrderBy(x => x.Timestamp) before .SelectMany().

return await DbContext.Items
    .Where(x => x.ItemNo== parentItemNo)
    .OrderBy(x => x.Timestamp)  // Sort by Timestamp first
    .SelectMany(x => x.Children.Select(c => new Child
    {
        ItemNo = c.ItemNo,
        ItemName = c.ItemName,
        GrandChildItemNos = c.Children.Select(gc => 
            new GrandChild 
            { 
                ItemNo = gc.ItemNo, 
                ItemName = gc.ItemName 
            })  
    })).ToListAsync();

CodePudding user response:

Have you tried something like this?

await DbContext.Items.Where(x => x.ItemNo == parentItemNo)
                .SelectMany(x => x.Children.OrderByDescending(t => t.Timestamp).Select(c => new Child
                {
                    ItemNo = c.ItemNo,
                    ItemName = c.ItemName,
                    Timestamp = c.Timestamp,
                    GrandChildItemNos = c.GrandChildItemNos.OrderByDescending(t => t.Timestamp).Select(gc =>
                          new GrandChild
                          {
                              ItemNo = gc.ItemNo,
                              ItemName = gc.ItemName,
                              Timestamp = gc.Timestamp,
                          })
                })).ToListAsync();
  • Related