mbursill
mbursill

Reputation: 3171

Merge flat list into hierarchy using LINQ

// simple EF projection (anonymous type returned)
var superHerosData = from hero in filteredHeros 
                     select new
                     {
                        hero.HeroId,
                        hero.FirstName
                        hero.LastName
                        Powers = from power in hero.Powers
                                 select new
                                 {
                                    power.PowerId;
                                 }
                    };

List<SuperHeroModel> superHeros = new List<SuperHeroModel>();

// populates superHeros (collection of SuperHeroModel) with the values in superHerosData
MapToModel(superHerosData, ref superHeros)

IQueryable<DAL.Models.Power> powersData = from hero in filteredHeros
                                          from power in hero.Powers
                                          select power;

Getting powers is expensive and has better performance if done in a single operation (flat collection)

List<PowerModel> powers = await GetPowers(powersData);

I need to replace the Powers collection inside each SuperHeroModel (of the superHeros collection) with a collection of the matching models from the powers collection.

What's a good LINQ-to-objects way to inject the flat list of powers into the hierarchy of superHeros? SuperHeroModel.Powers currently contains a collection of PowerModel with just the PowerId populated

Update:

Something like this might work, but it doesn't feel very Linq friendly. I was hoping for a more elegant solution:

foreach (SuperHeroModel superHero in superHeros)
{
    IEnumerable<int> superHeroPowerIds = superHero.Powers.Select(p => p.PowerId);
    List<PowerModel> superHeroPowers = powers.Where(power => superHeroPowerIds.Contains(power.PowerId)).ToList();

    superHero.Powers = superHeroPowers;
}

Upvotes: 2

Views: 754

Answers (1)

mayabelle
mayabelle

Reputation: 10014

This should work:

foreach (SuperHeroModel superHero in superHeros)
{
    IEnumerable<int> powerIds = superHero.Powers.Select(p => p.PowerId);
    superHeros.Powers = powers.Where(p => powerIds.Contains(p.PowerId));
}

Upvotes: 1

Related Questions