Search code examples
c#linq

Update the count property in the same object while grouping in linq C#


Class:

Contact{
        public int Id { get; set; }

        public string Email { get; set; }

        public string DisplayName { get; set; }
        
        public int DocCount { get; set; }

        public string DocName { get; set; }
        

}

I have a list of contacts which look like

var contactList = new List<Contact>(){ 
                           new Contact(){1,"[email protected]","ABC",0,"testdoc1"},
                           new Contact(){1,"[email protected]","ABC",0,"testdoc2"},
                           new Contact(){1,"[email protected]","ABC",0,"testdoc3"},
                           new Contact(){2,"[email protected]","XYZ",0,"testdoc1"},
                           new Contact(){2,"[email protected]","XYZ",0,"testdoc2"},
                           new Contact(){2,"[email protected]","XYZ",0,"testdoc3"},
                           new Contact(){3,"[email protected]","MOP",0,"testdoc1"},
                           new Contact(){3,"[email protected]","MOP",0,"testdoc2"},
}

I am looking for the output where I need to update the doc count based on the count of the documents uploaded by user.

output expected is:

{1,"[email protected]","ABC",3,"testdoc1 testdoc2 testdoc3"},
{2,"[email protected]","XYZ",3,"testdoc1 testdoc2 testdoc3"},
{3,"[email protected]","MOP",2,"testdoc1 testdoc2"}

is there is any way to do so, I know we can introduce new class and do it, but looking for something minimal


Solution

  • I would argue that updating instances via LINQ is not a good practice - just create a new instance of Contact:

    var result = contactList
        .GroupBy(c => c.Id)
        .Select(gr => new Contact
        {
            Id = gr.Key,
            Email = gr.First().Email,
            DisplayName = gr.First().DisplayName,
            DocCount = gr.Count(),
            DocName = string.Join(", ", gr.Select(c => c.DocName))
        })
        .ToList();
    

    Or if you expect variance in emails/display names:

    var result = contactList
        .GroupBy(c => (c.Id, c.Email, c.DisplayName))
        .Select(gr => new Contact
        {
            Id = gr.Key.Id,
            Email = gr.Key.Email,
            DisplayName = gr.Key.DisplayName,
            DocCount = gr.Count(),
            DocName = string.Join(", ", gr.Select(c => c.DocName))
        })
        .ToList();