LINQ Dynamic from DTO - Datetime Filtration

Asked

Viewed 137 times

0

I’m trying to assemble a dynamic filter from a Dtofiltro object that I get filled through the View. My problem is, when I try to filter the results that will be shown on the screen by Mesano, I cannot do a proper treatment of the data so that Linqtoentities can interpret the Where string that is mounted... I tried to collect some examples of the code to better exemplify the problem and left some of the solutions already tested that did not work.

The code is part of an MVC5 application I’m developing. And I don’t even know how to search for a solution to my problem...

The way the code is at the moment, I can pass the information from the service layer to the repository and query in the linqtoentities, but it does not return results, although I’m sure that there are data in the database that would be according to the query...

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

    //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>;
    }
  • Your question is very confusing. Try to be [Dit] and get better. I also suggest doing a summary at the beginning, succinctly saying: 1. What do you intend to do? 2. What went wrong and how did it go wrong?

  • Have you considered instead of assembling a string to return to the Where mount function, returning already a Iqueryable<Modeloedmx>? there you pass as parameter, beyond the filter, the Iqueryable<Modeloedmx>. Then you filter it into the function where it is needed, using the Linear itself avoiding magic strings, and return the Iqueryable<Modeloedmx> already with the proper filters. Got it?

  • @Leandrosimões I thought yes, my problem for this case is that the way the system was structured dictates that the services do not see the bank models, but only the repository and this yes, It has to access and manipulate bank objects.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.