WEB API with Entity Framework Core using the JOIN statement

Igor Baldacci 41 Reputation points
2021-10-11T10:38:10.19+00:00

Hi all,
I have written a WEB API with Entity Framework that read form two tables using the JOIN statement.

In order to obtain the wanted result, I have used vary solutions. The "Include" statement didn't work (I don't know why), so I have used the classic JOIN, and the procedure works fine.

But, I have needed to use a DTO model to "export" the joined data from the api.

Is this the correct way to accomplisce this kinde of work (reading data from joined tables)?

Is there more efficient way?

This is my Model

// MODEL (Giocata + TipoGiocata)    

    public class Giocata
    {
        public int GiocataId { get; set; }
        public string NomeGiocata { get; set; }
        public DateTime DataGiocata { get; set; }
        public string Numeri { get; set; }
        public bool Attiva { get; set; }

        // FK TipoGiocataId
        public int TipoGiocataId { get; set; }
        public TipoGiocata TipiGiocata { get; set; }
    }

    public class TipoGiocata
    {
        public int TipoGiocataId { get; set; }
        public string NomeTipoGiocata { get; set; }

        // FK Giocate
        public int GiocataId { get; set; }
        public ICollection<Giocata> Giocate { get; set; }
    }

// MODEL GiocataDTO

    public class GiocataDTO
    {
        // Giocate
        public int GiocataId { get; set; }
        public string NomeGiocata { get; set; }
        public DateTime DataGiocata { get; set; }
        public string Numeri { get; set; }
        public bool Attiva { get; set; }

        // TipoGiocata
        public int TipoGiocataId { get; set; }
        public string NomeTipoGiocata { get; set; }
    }

This is my WEB API:

        public async Task<ActionResult<IEnumerable<GiocataDTO>>> GetGiocate()
        {
            List<GiocataDTO> listaGiocateDTO = new List<GiocataDTO>();

            var listaGiocate = await _context.Giocate
                .Join(
                    _context.TipiGiocata,
                    giocata => giocata.TipoGiocataId,
                    tipogiocata => tipogiocata.TipoGiocataId,
                    (giocata, tipogiocata) => new
                    {
                        GiocataId = giocata.GiocataId,
                        NomeGiocata = giocata.NomeGiocata,
                        DataGiocata = giocata.DataGiocata,
                        Numeri = giocata.Numeri,
                        NomeTipoGiocata = tipogiocata.NomeTipoGiocata,
                        Attiva = giocata.Attiva
                    }
                ).ToListAsync();

            foreach (var giocata in listaGiocate)
            {
                GiocataDTO giocataDTO = new GiocataDTO();

                giocataDTO.GiocataId = giocata.GiocataId;
                giocataDTO.NomeGiocata = giocata.NomeGiocata;
                giocataDTO.DataGiocata = giocata.DataGiocata;
                giocataDTO.Numeri = giocata.Numeri;
                giocataDTO.NomeTipoGiocata = giocata.NomeTipoGiocata;
                giocataDTO.Attiva = giocata.Attiva;

                listaGiocateDTO.Add(giocataDTO);
            }

            return listaGiocateDTO;
        }

Thank you for your help.
Igor.

Entity Framework Core
Entity Framework Core
A lightweight, extensible, open-source, and cross-platform version of the Entity Framework data access technology.
696 questions
ASP.NET Core
ASP.NET Core
A set of technologies in the .NET Framework for building web applications and XML web services.
4,188 questions
0 comments No comments
{count} votes

3 answers

Sort by: Most helpful
  1. Bruce (SqlWork.com) 56,766 Reputation points
    2021-10-11T14:55:11.247+00:00

    Why create the anonymous object in the select rather than the desired?

    0 comments No comments

  2. Igor Baldacci 41 Reputation points
    2021-10-11T15:11:54.983+00:00

    Like this?

            [HttpGet]
            [Route("[action]")]
            [Route("api/giocate/GetGiocate")]
            public async Task<ActionResult<IEnumerable<Giocata>>> GetGiocate()
            {
                List<Giocata> listaGiocate = new List<Giocata>();
    
                listaGiocate = await _context.Giocate
                    .Join(
                        _context.TipiGiocata,
                        giocata => giocata.TipoGiocataId,
                        tipogiocata => tipogiocata.TipoGiocataId,
                        (giocata, tipogiocata) => new
                        {
                            GiocataId = giocata.GiocataId,
                            NomeGiocata = giocata.NomeGiocata,
                            DataGiocata = giocata.DataGiocata,
                            Numeri = giocata.Numeri,
                            NomeTipoGiocata = tipogiocata.NomeTipoGiocata,
                            Attiva = giocata.Attiva
                        }
                    ).ToListAsync();
    
                return listaGiocate;
            }
    

    If I do it, I receive the error in line 6:

    Error CS0029: Cannot implicitly convert type 'System.Collections.Generic.List<<anonymous type: int GiocataId, string NomeGiocata, System.DateTime DataGiocata, string Numeri, string NomeTipoGiocata, bool Attiva>>' to 'System.Collections.Generic.List<IreneLottoApi.Models.Giocata>'

    0 comments No comments

  3. Igor Baldacci 41 Reputation points
    2021-10-12T07:57:03.513+00:00

    Hi Bruce-SqlWork,
    your answer inspired me the solution: why using an anonymous object in the select?

    So, I have modified like this and now seems better:

            [HttpGet]
            [Route("[action]")]
            [Route("api/giocate/GetGiocate")]
            public async Task<ActionResult<IEnumerable<GiocataDTO>>> GetGiocate()
            {
                var listaGiocate = await _context.Giocate
                    .Join(
                        _context.TipiGiocata,
                        giocata => giocata.TipoGiocataId,
                        tipogiocata => tipogiocata.TipoGiocataId,
                        (giocata, tipogiocata) => new GiocataDTO
                        {
                            GiocataId = giocata.GiocataId,
                            NomeGiocata = giocata.NomeGiocata,
                            DataGiocata = giocata.DataGiocata,
                            Numeri = giocata.Numeri,
                            NomeTipoGiocata = tipogiocata.NomeTipoGiocata,
                            Attiva = giocata.Attiva
                        }
                    ).ToListAsync();
    
                return listaGiocate;
            }