Search code examples
c#linqgroup-bylinq-to-entities

LINQ - How to concatenate two fields in a Group By?


I have a ReportStatusEntity class as shown below:

public class ReportsStatusEntity
{
    public string PolicyNumber { get; set; }
    public string ClientName { get; set; }
    public bool HasIndividualBrokers { get; set; }
}

Let's say I have the following list of List<ReportStatusEntity>():

{PolicyNumber = 1, ClientName = "John Doe", HasIndividualBrokers = True},
{PolicyNumber = 1, ClientName = "Sarah Doe", HasIndividualBrokers = True},
{PolicyNumber = 2, ClientName = "Paul Smith", HasIndividualBrokers = False},
{PolicyNumber = 3, ClientName = "Ryan Johnson", HasIndividualBrokers = False}

I want to group by PolicyNumber, then concatenate the ClientNames having same PolicyNumber with '&'.

The grouping should be something like this:

{PolicyNumber = 1, ReportStatusEntity = (PolicyNumber = 1, ClientName = "John Doe & Sarah Doe", HasIndividualBrokers = True)},
{PolicyNumber = 2, ReportStatusEntity = (PolicyNumber = 2, ClientName = "Paul Smith", HasIndividualBrokers = False)},
{PolicyNumber = 3, ReportStatusEntity = (PolicyNumber = 3, ClientName = "Ryan Johnson", HasIndividualBrokers = False)}

How can this be done in C# using LINQ? Thank you.


Solution

  • var list = new List<ReportsStatusEntity>()
    {
        new ReportsStatusEntity{PolicyNumber = "1", ClientName = "John Doe", HasIndividualBrokers = true},
        new ReportsStatusEntity{PolicyNumber = "1", ClientName = "Sarah Doe", HasIndividualBrokers = true},
        new ReportsStatusEntity{PolicyNumber = "2", ClientName = "Paul Smith", HasIndividualBrokers = false},
        new ReportsStatusEntity{PolicyNumber = "3", ClientName = "Ryan Johnson", HasIndividualBrokers = false}
    };
    
    var results = list.GroupBy(r => r.PolicyNumber)
        .Select(g => new
        {
            PolicyNumber = g.Key,
            // string.Join will not work if its against a database with sql
            ClientNames = string.Join(" & ", g.Select(r => r.ClientName)),
        });
    
    foreach (var result in results)
    {
        Console.WriteLine($"Policy {result.PolicyNumber}: {result.ClientNames}");
    }
    
    // -- Outputs --
    // Policy 1: John Doe & Sarah Doe
    // Policy 2: Paul Smith
    // Policy 3: Ryan Johnson