replace a returned property with another property from a different model linking by Id

asp.net-core asp.net-core-3.0 asp.net-core-webapi entity-framework-core

Question

Hi I'm not quite sure how to do this.

I have this .NetCore EntityFrame controller that gets a list of characters.

It works when I simply get the list of characters by doing this:

return await _context.Character.ToListAsync();

This returns the name, class, race, age, armorPoints, hitPoints, and spiritAnimalId for each character in the database.

But now, instead of simply returning just the spiritAnimalId, I want to return the actual name of the animal.

So I started writing some code, but quickly lost the ability to figure out how to return the name of the spirit animal.

Here is what I have:

    // GET: api/Characters
    [HttpGet]
    public async Task<ActionResult<IEnumerable<Character>>> GetCharacters()
    {

        var characters= await _context.Character.ToListAsync();

        foreach(Character c in characters)
        {
            var a = _context.SpiritAnimal.FindAsync(c.spiritAnimalId);
            var name = a.Result.Name;
        }
        return charcters;
    }

So I'm lost as to how to return the list of projects and replace the spiritAnimalId with it's name.

NEW CODE:

    // GET: api/Characters
    [HttpGet]
    public async Task<ActionResult<List<Character>>> GetCharacters()
    {
         var characters = await _context.Character
                       .Select(x => new
                       {
                           x.Id,
                           x.Name,
                           x.Race,
                           x.Class,
                           x.Age,
                           SpiritAnimalName = x.SpiritAnimalName.Name
                        })
                       .ToListAsync();

        return characters;
    }

NEW ERROR:

Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type
to 'Microsoft.AspNetCore.Mvc.ActionResult<System.Collections.Generic.List

Thanks!

1
0
4/6/2020 5:35:23 PM

Accepted Answer

If you don't already, you should have a navigation property on your Character class like:

public SpiritAnimal SpiritAnimal { get; set; }

Then, when you make your query, you should include this relationship, so it's joined in the same query:

var characters = await _context.Character.Include(x => x.SpiritAnimal).ToListAsync();

As you're iterating over the characters, you can simply access: character.SpiritAnimal.Name. If you're wanting to only return the name from the query, you'll need to use Select to project into another class or an anonymous object:

var characters = await _context.Character
    .Select(x => new
    {
        CharacterName = x.Name,
        SpiritAnimalName = x.SpiritAnimal.Name
    }
    .ToListAsync();

When the Select expression utilizes a property on a related entity, you don't need to explicitly load it; EF is smart enough to realize it needs to do a join to satisfy the return.

1
4/6/2020 2:57:18 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow