SJMan
SJMan

Reputation: 1607

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

Upvotes: 0

Views: 463

Answers (2)

Jakub Kozera
Jakub Kozera

Reputation: 3483

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();

Upvotes: 0

user1672994
user1672994

Reputation: 10849

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.

Upvotes: 2

Related Questions