none
Alguna idea de como optimizar este codigo en Linq? RRS feed

  • Pregunta

  • Hola!

    Me pidieron que produjera un informe que es impulsado por una consulta en Linq bastante compleja en una base de datos de SQL Server.

    Logré terminar una versión, pero no es eficiente, necesito ayuda para optimizarlo.

    {
        IEnumerable<dynamic> data = new List<dynamic>();

        string filter = this.Request.Query["filter"];
        string search = this.Request.Query["search_input"];

        int idMechanic = Convert.ToInt32(this.Request.Query["mechanic_id"]);
        int totalAwardsAsign = 0;
        int winners =0;
        int minPoints=0;

        if( idMechanic > 0 )
        {
            totalAwardsAsign = _context.AwardAdjudication.Where( x => x.MechanicsId == idMechanic ).ToList().Count();
            Mechanics mec = _context.Mechanics.Where( x => x.Id == idMechanic ).First();
            winners = Convert.ToInt32( mec.Winners );
            minPoints = Convert.ToInt32( mec.WinOffset );

            data = (
                from dynMemR in _context.DynamicMemberRound group dynMemR by dynMemR.MemberCodeRedeemId into vr   
                    where vr.First().MechanicsId == idMechanic && vr.Sum( _=>_.EarnedPoints ) >= minPoints
                    join mem in _context.Members on vr.First().MembersId equals mem.Id

                from adj in  _context.AwardAdjudication
                    .Where( x => x.MechanicsId == vr.First().MechanicsId && x.MembersId == vr.First().MembersId )
                    .DefaultIfEmpty()

                select new
                {
                    RoundId = vr.First().Id,
                    Points = vr.Sum( _=>_.EarnedPoints ),
                    Time = vr.Sum( _=>_.TimeLapse ),
                    vr.First().Member.Name,
                    vr.First().Member.Email,
                    AwardName = ( adj == null ) ? "N/A" : adj.Award.Name
                }
            )
            .OrderByDescending( x=>x.Points )
            .ThenBy( x=>x.Time )
            .ToList();
        }

        return Ok(new{
                model = new {
                    data = data,
                    current_page = 0,
                    per_page = qparams.pageSize ?? _appsettings.GetValue<int>("Pagination:DefaultPageSize"),
                    total = data.Count(),
                    totalWinners = winners,
                    totalAwardsAssigned = totalAwardsAsign
                },
                columns = getColumns<Winner>(typeof(Winner))
            }
        );
    }
       





    • Editado Razzy25 jueves, 15 de noviembre de 2018 22:12 Se envía código completo
    jueves, 15 de noviembre de 2018 19:18

Respuestas

  • hola

    La verdad es que no llego a entender el objetivo del linq, pero que tengas dos "from" sin una conexion clara entre ellos genera ruido

    Veo que la union se da cuando usas: vr.First().MembersId

    eso esta muy raro

    Si usas Entity Framework porque no generas el mapping de navegacion entre las entidades DynamicMemberRound y AwardAdjudication, si puedes navegar als entidades quiere decir que se conectan por algun campo y haria la query mas simple

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    jueves, 15 de noviembre de 2018 19:47
  • Hola!

    Me pidieron que produjera un informe que es impulsado por una consulta en Linq bastante compleja en una base de datos de SQL Server.

    Logré terminar una versión, pero no es eficiente, necesito ayuda para optimizarlo.

    {
        IEnumerable<dynamic> data = new List<dynamic>();

        string filter = this.Request.Query["filter"];
        string search = this.Request.Query["search_input"];

        int idMechanic = Convert.ToInt32(this.Request.Query["mechanic_id"]);
        int totalAwardsAsign = 0;
        int winners =0;
        int minPoints=0;

        if( idMechanic > 0 )
        {
            totalAwardsAsign = _context.AwardAdjudication.Where( x => x.MechanicsId == idMechanic ).ToList().Count();
            Mechanics mec = _context.Mechanics.Where( x => x.Id == idMechanic ).First();
            winners = Convert.ToInt32( mec.Winners );
            minPoints = Convert.ToInt32( mec.WinOffset );

            data = (
                from dynMemR in _context.DynamicMemberRound group dynMemR by dynMemR.MemberCodeRedeemId into vr   
                    where vr.First().MechanicsId == idMechanic && vr.Sum( _=>_.EarnedPoints ) >= minPoints
                    join mem in _context.Members on vr.First().MembersId equals mem.Id

                from adj in  _context.AwardAdjudication
                    .Where( x => x.MechanicsId == vr.First().MechanicsId && x.MembersId == vr.First().MembersId )
                    .DefaultIfEmpty()

                select new
                {
                    RoundId = vr.First().Id,
                    Points = vr.Sum( _=>_.EarnedPoints ),
                    Time = vr.Sum( _=>_.TimeLapse ),
                    vr.First().Member.Name,
                    vr.First().Member.Email,
                    AwardName = ( adj == null ) ? "N/A" : adj.Award.Name
                }
            )
            .OrderByDescending( x=>x.Points )
            .ThenBy( x=>x.Time )
            .ToList();
        }

        return Ok(new{
                model = new {
                    data = data,
                    current_page = 0,
                    per_page = qparams.pageSize ?? _appsettings.GetValue<int>("Pagination:DefaultPageSize"),
                    total = data.Count(),
                    totalWinners = winners,
                    totalAwardsAssigned = totalAwardsAsign
                },
                columns = getColumns<Winner>(typeof(Winner))
            }
        );
    }
       






    La respuesta fue usar ADO para .Net
    • Marcado como respuesta Razzy25 martes, 27 de noviembre de 2018 5:40
    martes, 27 de noviembre de 2018 5:40

Todas las respuestas

  • hola

    La verdad es que no llego a entender el objetivo del linq, pero que tengas dos "from" sin una conexion clara entre ellos genera ruido

    Veo que la union se da cuando usas: vr.First().MembersId

    eso esta muy raro

    Si usas Entity Framework porque no generas el mapping de navegacion entre las entidades DynamicMemberRound y AwardAdjudication, si puedes navegar als entidades quiere decir que se conectan por algun campo y haria la query mas simple

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    jueves, 15 de noviembre de 2018 19:47
  • hola

    La verdad es que no llego a entender el objetivo del linq, pero que tengas dos "from" sin una conexion clara entre ellos ...


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    Te agradezco mucho tu respuesta, edite el código de la pregunta para poner el code completo, ojalá sirva para aclarar mi duda.
    jueves, 15 de noviembre de 2018 22:14
  • Hola!

    Me pidieron que produjera un informe que es impulsado por una consulta en Linq bastante compleja en una base de datos de SQL Server.

    Logré terminar una versión, pero no es eficiente, necesito ayuda para optimizarlo.

    {
        IEnumerable<dynamic> data = new List<dynamic>();

        string filter = this.Request.Query["filter"];
        string search = this.Request.Query["search_input"];

        int idMechanic = Convert.ToInt32(this.Request.Query["mechanic_id"]);
        int totalAwardsAsign = 0;
        int winners =0;
        int minPoints=0;

        if( idMechanic > 0 )
        {
            totalAwardsAsign = _context.AwardAdjudication.Where( x => x.MechanicsId == idMechanic ).ToList().Count();
            Mechanics mec = _context.Mechanics.Where( x => x.Id == idMechanic ).First();
            winners = Convert.ToInt32( mec.Winners );
            minPoints = Convert.ToInt32( mec.WinOffset );

            data = (
                from dynMemR in _context.DynamicMemberRound group dynMemR by dynMemR.MemberCodeRedeemId into vr   
                    where vr.First().MechanicsId == idMechanic && vr.Sum( _=>_.EarnedPoints ) >= minPoints
                    join mem in _context.Members on vr.First().MembersId equals mem.Id

                from adj in  _context.AwardAdjudication
                    .Where( x => x.MechanicsId == vr.First().MechanicsId && x.MembersId == vr.First().MembersId )
                    .DefaultIfEmpty()

                select new
                {
                    RoundId = vr.First().Id,
                    Points = vr.Sum( _=>_.EarnedPoints ),
                    Time = vr.Sum( _=>_.TimeLapse ),
                    vr.First().Member.Name,
                    vr.First().Member.Email,
                    AwardName = ( adj == null ) ? "N/A" : adj.Award.Name
                }
            )
            .OrderByDescending( x=>x.Points )
            .ThenBy( x=>x.Time )
            .ToList();
        }

        return Ok(new{
                model = new {
                    data = data,
                    current_page = 0,
                    per_page = qparams.pageSize ?? _appsettings.GetValue<int>("Pagination:DefaultPageSize"),
                    total = data.Count(),
                    totalWinners = winners,
                    totalAwardsAssigned = totalAwardsAsign
                },
                columns = getColumns<Winner>(typeof(Winner))
            }
        );
    }
       






    La respuesta fue usar ADO para .Net
    • Marcado como respuesta Razzy25 martes, 27 de noviembre de 2018 5:40
    martes, 27 de noviembre de 2018 5:40