MaciekB
MaciekB

Reputation: 61

Child list in join statement - LINQ

I have 3 collections

List<Brand> brands= new List<Brand>
{
    new Brand { ID = 5, Name = "Toyota"},
    new Brand { ID = 6, Name = "Mazda"},
    new Brand { ID = 7, Name = "Seat"}
};


ModelParam par1 = new ModelParam() { Id = 1, fuelType = "Petrol", enginePower =110, engineTorque = 130 };
ModelParam par2 = new ModelParam() { Id = 2, fuelType = "Petrol", enginePower = 170, engineTorque = 290 };
ModelParam par3 = new ModelParam() { Id = 3, fuelType = "Diesel", enginePower = 140, engineTorque = 280 };
ModelParam par4 = new ModelParam() { Id = 4, fuelType = "Diesel", enginePower = 190, engineTorque = 320 };

List<Model> models = new List<Model>
{
    new Model { Id = 1, Name = "CX5", brandId = 6, parameters = new List<ModelParam> {par1, par3} },
    new Model { Id = 2, Name = "Corolla", brandId = 5, parameters = new List<ModelParam> {par2, par3} },
    new Model { Id = 3, Name = "Leon", brandId = 7, parameters = new List<ModelParam> {par2, par4} }
};

As a result I want to have a query with combination of: Brand - Model - FuelType - EnginePower. I wrote this to join brands and model lists:

var result = models.Join(brands, 
    mod => mod.brandId, 
    b => b.ID, 
    (mod, b) => new { b.Name, mod.Name })
.ToList();

The problem is I can't extract fuelType and enginePower from ModelParams from params property in models List. Any tips?

Upvotes: 1

Views: 63

Answers (2)

Pavel Anikhouski
Pavel Anikhouski

Reputation: 23228

You should update your result selector Func a little bit and get the required values fuelType and enginePower from parameters collection in Model class. The following snippet will select only the first fuelType from parameters and max enginePower.

var result = models
    .Join(brands, mod => mod.brandId, b => b.ID,
    (mod, b) => new
    {
        Brand = b.Name,
        Model = mod.Name,
        FuelType = mod.parameters.Select(p => p.fuelType).FirstOrDefault(),
        EnginePower = mod.parameters.Max(p => p.enginePower)
    })
    .ToList();

However, there a situation when model can have multiple values for fuelType and enginePower.

If you need to choose all combinations, just look through the parameters collection and then flatten a result using SelectMany

var result = models
    .Join(brands, mod => mod.brandId, b => b.ID,
    (mod, b) => mod.parameters.Select(p => new
    {
        Brand = b.Name,
        Model = mod.Name,
        FuelType = p.fuelType,
        EnginePower = p.enginePower
    }))
    .SelectMany(_ => _)
    .ToList();

Upvotes: 1

J&#243;zef Podlecki
J&#243;zef Podlecki

Reputation: 11283

Can this approach work for you?

var result = models.Join(
    brands,
    mod => mod.brandId,
    b => b.ID,
    (mod, b) => mod.parameters.Select(parameter => new { 
       Brand = b.Name,
       Model = mod.Name,
       FuelType = parameter.fuelType,
       EnginePower = parameter.enginePower 
    }))
       .SelectMany(pr => pr)
       .ToList();

Upvotes: 1

Related Questions