Search code examples
c#linqprojection

LINQ Projection AFTER optional parameter filtering


I have this function in a class:

public IEnumerable<PedidosList> Pedidos_Listar(string sComprobante, Clientes MyCliente = null, DateTime? dDesde = null, DateTime? dHasta = null, bool bCumplidos = false)
{           
    using (var context = new OhmioEntities())
    {
        IEnumerable<PedidosList> query =
            from Pedidos in context.Pedidos
            join Clientes in context.Clientes on Pedidos.ID_Cliente equals Clientes.ID_Cliente
            where Pedidos.ID_Comprobante == sComprobante                    
            select new PedidosList {ID_Pedido = Pedidos.ID_Pedido, Fecha=Pedidos.Fecha, Aprobado=Pedidos.Aprobado, Bruto=Pedidos.Bruto, Cliente=Clientes.RazonFantasia, 
                FechaEntrega=Pedidos.FechaEntrega, Neto=Pedidos.Neto, Numero=Pedidos.Numero, Observaciones=Pedidos.Observaciones, Entregado=Pedidos.Entregado, ID_Cliente=Pedidos.ID_Cliente };

        if (MyCliente != null) query = query.Where(i => i.ID_Cliente == MyCliente.ID_Cliente);
        if (MyCliente != null) query = query.Where(i => i.ID_Cliente == MyCliente.ID_Cliente);
        if (dDesde != null && dHasta != null) query = query.Where(i => i.Fecha >= dDesde && i.Fecha <= dHasta);
        if (bCumplidos == false) query = query.Where(i => i.Entregado == false);                
        return query.ToList();
    }
}

The idea is to use LINQ projection to fill a custom class object where multiple optional filter parameters are evaluated. My question is: For performance and encapsulation reasons, can I make the projection AFTER optional where filters are applied? In my code the projection is done BEFORE, so i can only filter by the fields on my custom class, but i want to filter over the original class fields. Thank you.


Solution

  • var query =
        from Pedidos in context.Pedidos
        join Clientes in context.Clientes on Pedidos.ID_Cliente equals Clientes.ID_Cliente
        where Pedidos.ID_Comprobante == sComprobante      
        select new { Pedidos, Clientes };              
    
    if (MyCliente != null)
    {
        query = query.Where(i => i.Pedidos.ID_Cliente == MyCliente.ID_Cliente);
        query = query.Where(i => i.Periodos.ID_Cliente == MyCliente.ID_Cliente);
    }
    if (dDesde != null && dHasta != null)
        query = query.Where(i => i.Pedidos.Fecha >= dDesde && i.Pedidos.Fecha <= dHasta);
    if (bCumplidos == false)
        query = query.Where(i => i.Pedidos.Entregado == false);      
    
    return (from x in query
            let Pedidos = x.Pedidos
            let Clientes = x.Clientes
            select new PedidosList {ID_Pedido = Pedidos.ID_Pedido, Fecha=Pedidos.Fecha, Aprobado=Pedidos.Aprobado, Bruto=Pedidos.Bruto, Cliente=Clientes.RazonFantasia, FechaEntrega=Pedidos.FechaEntrega, Neto=Pedidos.Neto, Numero=Pedidos.Numero, Observaciones=Pedidos.Observaciones, Entregado=Pedidos.Entregado, ID_Cliente=Pedidos.ID_Cliente
            }).ToList();