I'm trying to take a list of doctor with locations. each row contains doctor information along with a location. Doctor "A" might have 3 locations so doctor "A" would have 3 rows. I would like to somehow group using linq to take this list to create a new doctor class with a List.

Here is my initial list.  Each row duplicates ProviderId and Name if the provider has more than one location
var providerLocation = new List<ProviderLocation>
        {
            new ProviderLocation
            {
                ProviderId = "1",
                FirstName = "Provider1",
                AddressId = "1",
                City = "Des Moines"
            },
            new ProviderLocation
            {
                ProviderId = "1",
                FirstName = "Provider1",
                AddressId = "2",
                City = "Urbandale"
            },
            new ProviderLocation
            {
                ProviderId = "2",
                FirstName = "Provider2",
                AddressId = "3",
                City = "Dallas"
            },
            new ProviderLocation
            {
                ProviderId = "2",
                FirstName = "Provider2",
                AddressId = "4",
                City = "Fort Worth"
            }
        };

would like it to go into new classs that looks like:

 public class Doctor
 {
    public string ProviderId { get; set; }
    public string FirstName { get; set; }
    public List<DoctorLocation> Locations { get; set; }
 }

 public class DoctorLocation
 {
    public string AddressId { get; set; }
    public string City { get; set; }
 }

Then I could reference my doctor list by:
var doctorList = List<Doctor>

Is there a way to make this happen using linq without having to loop through the list to manually populate the new classes?

2 Answers

0
Green On Best Solutions

Does this produce your desired result ?

var doctorList = providerLocation
    .GroupBy(pl => new { pl.ProviderId, pl.FirstName })
    .Select(group => new Doctor()
    {
        ProviderId = group.Key.ProviderId,
        FirstName = group.Key.FirstName,
        Locations = group.Select(dl => new DoctorLocation()
        {
             AddressId = dl.AddressId,
             City = dl.City
        }).ToList()
    })
    .ToList();

Result: enter image description here

This LINQ GroupBy your ProviderLocation, returning a list of IGrouping with key being an anonymous object of ProviderId and FirstName.

We get a Doctor for every IGrouping ( taken from group.Key properties )

Then we do a Select on this IGrouping, returning a DoctorLocation for every Item this IGrouping contains.

0
Tejas Parnerkar On

You can use the ConvertAll method. This is one way to do it -

public static List<Doctor> MakeDoctorsListFrom(List<ProviderLocation> providerLocations)
    {
        return providerLocations.ConvertAll<Doctor>((input) => new Doctor()
        {
            ProviderId = input.ProviderId,
            FirstName = input.FirstName,
            Locations = new List<DoctorLocation>(){
                new DoctorLocation(){
                    AddressId = input.AddressId,
                    City = input.City
                }
            }
        });
    }

And you call it from your code -

var doctors = MakeDoctorsCollectionFrom(providerLocation);