简体   繁体   中英

Convert DataTable to a nested object using LINQ

I have a stored proc returning a datatable using a stored procedure. I am able to convert the it to an object using the following code outgoingPaymentData.AsEnumerable().Select(x => new OutgoingPaymentApprovalDetails() { });

Here is my OutgoingPaymentApprovalDetails class

 public class OutgoingPaymentApprovalDetails
 {
    public int OriginatorId { get; set; }

    public string Name { get; set; }

    public string DocumentId { get; set; }

    public string DebtorName { get; set; }

    public string Currency { get; set; }

    public double Amount { get; set; }

    public string Description { get; set; }

    public string DebitAccountNo { get; set; }

    public string CreditAccountNo { get; set; }
}

Now, instead of a flat list, I need to add heirarchy, to select this one object to 3 objects.

Classes as under:

public class OriginatorDetails
{
     public int OriginatorId { get; set; }
     public string Name { get; set; }
     public List<DocumentDetails> DocumentDetails { get; set; }

}

public class DocumentDetails
{
   public string DocumentId { get; set; }
   public List<TransactionDetails> TransactionDetails { get; set; }
}
public class TransactionDetails
{
   public string Amount { get; set; }
   public string DebitAccountNo { get; set; }
   public string CreditAccountNo { get; set; }
}

Basically, All Documents of a particular Originator have to be in the list of DocumentDetails and all TransactionDetails of a particular document have to be in that list.

One way is to create a dictionary and add stuff in it and finally create an object. I was wondering if there was a more abbreviated and efficient way to do something like this. TIA

You can do the grouping of retrieved records of OutgoingPaymentApprovalDetails using Linq to create the nested object of OriginatorDetails collection.

see below code

var originalDetails = inputs.GroupBy(g => g.OriginatorId)
                      .Select(g => new OriginatorDetails() 
                      { 
                           OriginatorId = g.Key, 
                           Name = g.First().Name, 
                           DocumentDetails = g.GroupBy(d => d.DocumentId)
                                    .Select(d => new DocumentDetails() 
                                     {
                                            DocumentId = d.Key,
                                            TransactionDetails = d.Select(t => new TransactionDetails() 
                                            { 
                                                DebitAccountNo = t.DebitAccountNo,
                                                CreditAccountNo = t.CreditAccountNo, 
                                                Amount = t.Amount.ToString() 
                                            }).ToList()
                                     })
                                    .ToList() 
                     });

Check the created https://dotnetfiddle.net/FCA7Qc to demostrate your scenario.

Try this code: Basically you need to group 2 times, first time by OriginatorId and Name and then by DocumentId like this:

            var result = list.GroupBy(c => new {c.OriginatorId, c.Name})
                .Select(g => new OriginatorDetails()
                {
                    Name = g.Key.Name,
                    OriginatorId = g.Key.OriginatorId,
                    DocumentDetails = g
                        .GroupBy(dd => dd.DocumentId)
                        .Select(dd => new DocumentDetails()
                        {
                            DocumentId = dd.Key,
                            TransactionDetails = dd.ToList()
                                .Select(td => new TransactionDetails()
                                {
                                    Amount = td.Amount.ToString(),
                                    CreditAccountNo = td.CreditAccountNo,
                                    DebitAccountNo = td.DebitAccountNo
                                }).ToList()
                        }).ToList()
                }).ToList();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM