ASP. NET Core Web API, загрузка вложенных моделей - PullRequest
0 голосов
/ 16 апреля 2020

Я новичок в ASP. NET Core Web API и пытаюсь загрузить вложенную дочернюю модель, возвращая значения из API. Вот мой код:

Таблица Элементы содержат продукты питания Таблица Меню содержат меню Таблица MenuItems отображает элемент в меню

Вот мои модели:

Модель изделия

namespace FoodDeliveryServer.Models
{
[Table("Items")]
public class Item
{
    public long Id { get; set; }

    public string Name { get; set; }
    public string ImageName { get; set; }
    public string Description { get; set; }
    public string SavedImageName { get; set; }
    public string ShortDescription { get; set; }

    public double Price { get; set; }

    public bool IsActive { get; set; }
    public DateTime UpdateAt { get; set; }
    public DateTime CreatedAt { get; set; }
}
}

Модель меню

namespace FoodDeliveryServer.Models
{
[Table("Menus")]
public class Menu
{
    public long Id { get; set; }

    public string Name { get; set; }
    public string Image { get; set; }
    public string LongDescription { get; set; }
    public string ShortDescription { get; set; }

    public ICollection<MenuItem> MenuItems { get; set; }

    public bool IsActive { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
}

MenuItem модель

namespace FoodDeliveryServer.Models
{
[Table("MenuItems")]
public class MenuItem
{
    public long Id { get; set; }
    public long ItemId { get; set; }
    public long MenuId { get; set; }

    public string Description { get; set; }

    public virtual Item Item { get; set; }

    public bool IsActive { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
}
}

А вот код контроллера:

namespace FoodDeliveryServer.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class MenusController : ControllerBase
{
    private readonly FoodDeliveryContext _context;

    public MenusController(FoodDeliveryContext context)
    {
        _context = context;
    }

    // GET: api/Menus
    [HttpGet]
    public IEnumerable<Menu> GetMenu_1()
    {
        return _context.Menu;
    }

    // GET: api/Menus/5
    [HttpGet("{id}")]
    public async Task<IActionResult> GetMenu([FromRoute] long id)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var menu = _context.Menu.Include(m => m.MenuItems).Where(m => m.Id == id).First();

        if (menu == null)
        {
            return NotFound();
        }

        return Ok(menu);
    }

    // PUT: api/Menus/5
    [HttpPut("{id}")]
    public async Task<IActionResult> PutMenu([FromRoute] long id, [FromBody] Menu menu)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != menu.Id)
        {
            return BadRequest();
        }

        _context.Entry(menu).State = EntityState.Modified;

        try
        {
            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!MenuExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return NoContent();
    }

    // POST: api/Menus
    [HttpPost]
    public async Task<IActionResult> PostMenu([FromBody] Menu menu)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        _context.Menu.Add(menu);
        await _context.SaveChangesAsync();

        return CreatedAtAction("GetMenu", new { id = menu.Id }, menu);
    }

    // POST: api/Menus/filter
    [HttpPost]
    [Route("filter", Name = "Filtermenu")]
    public async Task<IActionResult> FilterMenu([FromBody] Menu menu)
    {
        return Ok(_context.Menu.Include(m=>m.MenuItems).ThenInclude(i=>i.Item).Where(m => m.IsActive == menu.IsActive));
    }

    // DELETE: api/Menus/5
    [HttpDelete("{id}")]
    public async Task<IActionResult> DeleteMenu([FromRoute] long id)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var menu = await _context.Menu.FindAsync(id);
        if (menu == null)
        {
            return NotFound();
        }

        _context.Menu.Remove(menu);
        await _context.SaveChangesAsync();

        return Ok(menu);
    }

    private bool MenuExists(long id)
    {
        return _context.Menu.Any(e => e.Id == id);
    }

    public class MenuFilter
    {
        public bool isActive { get; set; }
    }
}
}

Это никогда не загружает дочерний элемент, поэтому мне пришлось использовать Включить

return _context.Menu.FindAsync(id);

В ответ я получаю:

{
 "id": 25,
 "name": "acd",
 "image": null,
 "longDescription": "cacc",
 "shortDescription": "def",
 "menuItems": [
 {
  "id": 5,
  "itemId": 1,
  "menuId": 25,
  "description": "abc",
  "item": null,
  "isActive": true,
  "createdAt": "2000-01-01T00:00:00",
  "updatedAt": "0001-01-01T00:00:00"
},
{
  "id": 10002,
  "itemId": 1,
  "menuId": 25,
  "description": null,
  "item": null,
  "isActive": false,
  "createdAt": "0001-01-01T00:00:00",
  "updatedAt": "0001-01-01T00:00:00"
},
{
  "id": 10003,
  "itemId": 1,
  "menuId": 25,
  "description": null,
  "item": null,
  "isActive": false,
  "createdAt": "0001-01-01T00:00:00",
  "updatedAt": "0001-01-01T00:00:00"
}
],
"isActive": true,
"createdAt": "0001-01-01T00:00:00",
"updatedAt": "0001-01-01T00:00:00"
}

Что мне делать, чтобы получить Item также внутри объекта массива menuItems?

Я также пытался:

_context.Menu.Include(m => m.MenuItems).ThenInclude(i=>i.Item).Where(m => m.Id == id).First();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...