Dynamic LINQ from DTO - DateTime filtering

0

I'm trying to mount a dynamic filter from a DTOFilter object that I get populated through the View. My problem is, when I try to filter the results that will be shown on the screen by MesAno, I can not properly handle the data so that LinqToEntities can interpret the string from where it is mounted ... I tried to collect some examples of the code to better exemplify the problem and left one of the already tested solutions that did not work.

The code is part of an MVC5 application I'm developing. And I do not even know how to search for a solution to my problem ...

As the code is currently, I can pass the service layer information to the repository and query it in linqtoentities, but it does not return results, although I'm sure there's data in the database that is supposed to be according to the query ...

What is the ideal way to handle this case? Is there any easier way to build a dynamic string for the database object .Where?

    //MeuModeloService.cs
    public class MeuModeloService : IService<DTOFiltroMeuModelo, DTOMeuModelo>
    {
        private IRepositorioMeuModelo _repoMeuModelo;
        //...
        public MeuModeloService()
        {
            _repoMeuModelo = new RepositorioMeuModelo();
            //...
        }
        //...
        //Métodos de serviço abaixo
        //...
    }
    public string MontaWhere(DTOFiltroMeuModelo filtros)
    {
        string filtroCustomizado = " 1 = 1 ";

        if (filtros.IdPerfil > 0)
            filtroCustomizado += " and IdPerfilCCEE = " + filtros.IdPerfil;

        if (filtros.IdAgente > 0 && filtros.IdPerfil == 0)
        {
            List<int> lstIdPerfil = _repoPerfil.Listar("IdAgente = " + filtros.IdAgente).Select(x => x.Id).ToList();
            foreach (var idPerfil in lstIdPerfil)
            {
                filtroCustomizado += " and IdPerfilCCEE = " + idPerfil + "";
            }
        }

        if (filtros.IdCliente > 0)
            filtroCustomizado += " and IdCliente = " + filtros.IdCliente + "";

        if (filtros.IdUnidade > 0)
            filtroCustomizado += " and IdUnidade = " + filtros.IdUnidade + "";

        if (!string.IsNullOrEmpty(filtros.MesAno))
        {
            var MesAnoSplit = filtros.MesAno.Split('/');
            filtroCustomizado += " and string.Equals((MesAno.Year.ToString() + \"-\" + MesAno.Month.ToString() + \"-\" + MesAno.Day.ToString()), \"" + MesAnoSplit[2] + "-" + MesAnoSplit[1] + "-" + MesAnoSplit[0] + "\")";

            //Outras abordagens de solução
            //filtroCustomizado += " and MesAno.ToString(\"yyyy-mm-dd\") = \"" + MesAnoSplit[2] + "-" + MesAnoSplit[1] + "-" + MesAnoSplit[0] + "\"";
            //filtroCustomizado += " and MesAno = DateTime.Parse(\"" + MesAnoSplit[0] + "-" + MesAnoSplit[1] + "-" + MesAnoSplit[2] + "\")";
            //filtroCustomizado += " and MesAno = DateTime.ParseExact(\"" + MesAnoSplit[2] + "-" + MesAnoSplit[1] + "-" + MesAnoSplit[0] + "\", \"YYYY-MM-DD\", new CultureInfo(\"en-US\"))";
        }

        return filtroCustomizado;
    }


    public int BuscarNumeroTotalDeItens(DTOFiltroMeuModelo filtros)
    {
        return _repoMeuModelo.NumTotalLista(MontaWhere(filtros));
    }

    public List<DTOMeuModelo> ListarComPaginacao(DTOFiltroMeuModelo filtros)
    {
        DTOPaginacao paginacao = filtros.Paginacao;

        string where = string.Empty;
        int itemPorPag = paginacao.ItemPorPagina;
        int limiteInicial = 0;
        int limiteFinal = itemPorPag;
        string ordem = filtros.Ordem + " " + filtros.TipoOrdem;

        where = MontaWhere(filtros);

        if (paginacao.Pagina > 0)
        {
            limiteInicial = (paginacao.Pagina - 1) * itemPorPag;
        }

        List<DTOMeuModelo> listagem = new List<DTOMeuModelo>();

        foreach (var item in _repoMeuModelo.Listar(where, limiteInicial, limiteFinal, ordem))
        {
            var dtoModelo = new DTOMeuModelo(item, false);
            listagem.Add(dtoModelo);
        }

        return listagem;
    }


    //---------------------------------------------------------------------
    //DTOFiltroMeuModelo.cs

    public class DTOFiltroMeuModelo
    {
        [Display(Name = "Cliente")]
        public int IdCliente { get; set; }
        [Display(Name = "Perfil")]
        public int IdPerfil { get; set; }
        [Display(Name = "Agente")]
        public int IdAgente { get; set; }
        [Display(Name = "Unidade")]
        public int IdUnidade { get; set; }
        [Display(Name = "Mês/Ano")]
        public string MesAno { get; set; }
        public string Ordem { get; set; }
        public string TipoOrdem { get; set; }
        public DTOPaginacao Paginacao { get; set; }

        public DTOFiltroMeuModelo()
        {
            this.Ordem = "Id";
            this.TipoOrdem = "DESC";
        }
    }

    //---------------------------------------------------------------------
    //RepositorioMeuModelo.cs

    public IEnumerable<ModeloEDMX> Listar(string filtroCustomizado, int limiteInicial, int limiteFinal, string orderBy)
    {
        IQueryable<ModeloEDMX> queryFiltro = BancoDeDados.ModeloEDMX.AsQueryable();

        if (filtroCustomizado != "")
            queryFiltro = queryFiltro.Where(filtroCustomizado);

        var listaRegistroExcluido = from registros in BancoDeDados.SmartRegistro
                          join entidade in BancoDeDados.ModeloEDMX on registros.IdRegistro equals entidade.Id into merge
                          from filtrado in merge.DefaultIfEmpty()
                          where registros.Tabela == "ModeloEDMX" && (registros.Status == 6 || registros.Status == 12)
                          select filtrado;

        var queryResult = queryFiltro.Except(listaRegistroExcluido);

        queryResult = MontaQueryLimites(queryResult, limiteInicial, limiteFinal, orderBy);

        var lstDados = queryResult.ToList();

        return lstDados as IEnumerable<ModeloEDMX>;
    }
    
asked by anonymous 10.08.2017 / 22:09

0 answers