Cast Linq错误

时间:2011-12-07 21:28:06

标签: linq entity-framework ienumerable

我在制作剧组时遇到了麻烦。 有什么建议吗?

感谢。

错误:LINQ to Entities无法识别方法'System.DateTime ToDateTime(System.String)'方法,并且此方法无法转换为商店表达式。

public IEnumerable<documento> BuscarDocumento(string jsonBusca, out int quantidadeTotalDocumentos, int chave)
        {
            try
            {
                ValidaSessaoUsuario(chave);
                DateTime dataDe;
                DateTime dataAte;

                // TODO Permissões - TipoDocumento
                var contexto = new Contexto();
                var documentoBusca = JsonConvert.DeserializeObject<DocumentoBusca>(jsonBusca);

                IEnumerable<documento> querylinq = contexto.documentoes
                    .Include("documento_indice")
                    .Where(a => a.id_tipodocumento == documentoBusca.id_tipodocumento && a.ativo == true);

                if (!String.IsNullOrEmpty(documentoBusca.dataDe) && String.IsNullOrEmpty(documentoBusca.dataAte))
                {
                    dataDe = DateTime.Parse(documentoBusca.dataDe);
                    querylinq = querylinq.Where(a => a.timestamp >= dataDe && a.timestamp <= DateTime.Now);
                }
                else if (String.IsNullOrEmpty(documentoBusca.dataDe) && !String.IsNullOrEmpty(documentoBusca.dataAte))
                {
                    dataAte = DateTime.Parse(documentoBusca.dataAte);
                    querylinq = querylinq.Where(a => a.timestamp <= dataAte);
                }
                else if (!String.IsNullOrEmpty(documentoBusca.dataDe) && !String.IsNullOrEmpty(documentoBusca.dataAte))
                {
                    dataDe = DateTime.Parse(documentoBusca.dataDe);
                    dataAte = DateTime.Parse(documentoBusca.dataAte).AddDays(1);
                    querylinq = querylinq.Where(a => a.timestamp >= dataDe && a.timestamp <= dataAte);
                }      

                foreach (var indice in documentoBusca.IndiceBusca)
                {
                    switch (indice.tipoDado)
                    {
                        case (int)Tipo.String:
                        case (int)Tipo.ComboBox:
                            querylinq = querylinq.Join(
                            contexto.documento_indice.Where(a => a.id_indice == indice.id && a.valor == indice.valor),
                            doc => doc.id, ind => ind.id_documento, (doc, ind) => doc);                            
                            break;
                        case(int)Tipo.Inteiro:
                            querylinq = querylinq.Join(contexto.documento_indice.Where(ObterPredicadoInteiro(indice)),
                            doc => doc.id, ind => ind.id_documento, (doc, ind) => doc);                              
                            break;
                        case (int)Tipo.Data:
                            querylinq = querylinq.Join(
                            contexto.documento_indice.Where(ObterPredicadoData(indice)),
                            doc => doc.id, ind => ind.id_documento, (doc, ind) => doc);                             
                            break;
                    }
                }

                quantidadeTotalDocumentos = querylinq.Count();

                return querylinq
                    .OrderBy(a => a.id)
                    .Skip(documentoBusca.resultado_inicial)
                    .Take(documentoBusca.resultados_pagina); 
            }
            catch (FaultException<DetalhesErro> e)
            {
                throw e;
            }
            catch (Exception e)
            {
                DetalhesErro tokenErro = new DetalhesErro(e, "Erro ao buscar a lista de documentos.");
                throw new FaultException<DetalhesErro>(tokenErro, new FaultReason(tokenErro.mensagemCurta));
            }
        }

        private Expression<Func<documento_indice, bool>> ObterPredicadoString(IndiceBusca indice)
        {
            try
            {
                switch (indice.operador)
                {
                    case "=":
                        return a => a.id_indice == indice.id && a.valor == indice.valor;
                    case "A*":
                        return a => a.id_indice == indice.id && a.valor.StartsWith(indice.valor);
                    case "*A*":
                        return a => a.id_indice == indice.id && a.valor.Contains(indice.valor);
                    case "<>":
                        return a => a.id_indice == indice.id && a.valor != indice.valor;                    
                    default:
                        return a => true;
                }
            }
            catch (FaultException<DetalhesErro> e)
            {
                throw e;
            }
            catch (Exception e)
            {
                DetalhesErro tokenErro = new DetalhesErro(e, "Erro ao obter o predicado.");
                throw new FaultException<DetalhesErro>(tokenErro, new FaultReason(tokenErro.mensagemCurta));
            }
        }

        private Expression<Func<documento_indice, bool>> ObterPredicadoInteiro(IndiceBusca indice)
        {
            try
            {
                int valorInt = int.Parse(indice.valor);

                switch (indice.operador)
                {
                    case "=":
                        return a => a.id_indice == indice.id && Convert.ToInt32(a.valor) == valorInt;                   
                    case "<>":
                        return a => a.id_indice == indice.id && Convert.ToInt32(a.valor) != valorInt;
                    case ">":
                        return a => a.id_indice == indice.id && Convert.ToInt32(a.valor) > valorInt;
                    case "<":
                        return a => a.id_indice == indice.id && Convert.ToInt32(a.valor) < valorInt;
                    case ">=":
                        return a => a.id_indice == indice.id && Convert.ToInt32(a.valor) >= valorInt;
                    case "<=":
                        return a => a.id_indice == indice.id && Convert.ToInt32(a.valor) <= valorInt;
                    default:
                        return a => true;
                }
            }
            catch (FaultException<DetalhesErro> e)
            {
                throw e;
            }
            catch (Exception e)
            {
                DetalhesErro tokenErro = new DetalhesErro(e, "Erro ao obter o predicado.");
                throw new FaultException<DetalhesErro>(tokenErro, new FaultReason(tokenErro.mensagemCurta));
            }
        }

        private Expression<Func<documento_indice, bool>> ObterPredicadoData(IndiceBusca indice)
        {
            try
            {
                DateTime data = Convert.ToDateTime(indice.valor);

                switch (indice.operador)
                {
                    case "=":
                        return a => a.id_indice == indice.id && Convert.ToDateTime(a.valor) == data;  
                    case "<>":
                        return a => a.id_indice == indice.id && Convert.ToDateTime(a.valor) != data;
                    case ">":
                        return a => a.id_indice == indice.id && Convert.ToDateTime(a.valor) > data;
                    case "<":
                        return a => a.id_indice == indice.id && Convert.ToDateTime(a.valor) < data;
                    case ">=":
                        return a => a.id_indice == indice.id && Convert.ToDateTime(a.valor) >= data;
                    case "<=":
                        return a => a.id_indice == indice.id && Convert.ToDateTime(a.valor) <= data;
                    default:
                        return a => true;
                }
            }
            catch (FaultException<DetalhesErro> e)
            {
                throw e;
            }
            catch (Exception e)
            {
                DetalhesErro tokenErro = new DetalhesErro(e, "Erro ao obter o predicado.");
                throw new FaultException<DetalhesErro>(tokenErro, new FaultReason(tokenErro.mensagemCurta));
            }
        }

1 个答案:

答案 0 :(得分:0)

我解决了这个问题。 需要立即加载     contexto.documento_indice。的 ToList()。凡(ObterPredicadoInteiro(指数之)) 并更改方法以返回Func ...

完全解决。

public IEnumerable<documento> BuscarDocumento(string jsonBusca, out int quantidadeTotalDocumentos, int chave)
    {
        try
        {
            ValidaSessaoUsuario(chave);
            DateTime dataDe;
            DateTime dataAte;

            // TODO Permissões - TipoDocumento
            var contexto = new Contexto();
            var documentoBusca = JsonConvert.DeserializeObject<DocumentoBusca>(jsonBusca);

            IEnumerable<documento> querylinq = contexto.documentoes
                .Include("documento_indice")
                .Where(a => a.id_tipodocumento == documentoBusca.id_tipodocumento && a.ativo == true);


            if (!String.IsNullOrEmpty(documentoBusca.dataDe) && String.IsNullOrEmpty(documentoBusca.dataAte))
            {
                dataDe = DateTime.Parse(documentoBusca.dataDe);
                querylinq = querylinq.Where(a => a.timestamp >= dataDe && a.timestamp <= DateTime.Now);
            }
            else if (String.IsNullOrEmpty(documentoBusca.dataDe) && !String.IsNullOrEmpty(documentoBusca.dataAte))
            {
                dataAte = DateTime.Parse(documentoBusca.dataAte);
                querylinq = querylinq.Where(a => a.timestamp <= dataAte);
            }
            else if (!String.IsNullOrEmpty(documentoBusca.dataDe) && !String.IsNullOrEmpty(documentoBusca.dataAte))
            {
                dataDe = DateTime.Parse(documentoBusca.dataDe);
                dataAte = DateTime.Parse(documentoBusca.dataAte).AddDays(1);
                querylinq = querylinq.Where(a => a.timestamp >= dataDe && a.timestamp <= dataAte);
            }

            if (documentoBusca.IndiceBusca != null && documentoBusca.IndiceBusca.Count() > 0)
            {
                foreach (var indice in documentoBusca.IndiceBusca)
                {
                    switch (indice.tipoDado)
                    {
                        case (int)Tipo.String:
                        case (int)Tipo.ComboBox:
                            querylinq = querylinq.Join(
                            contexto.documento_indice.Where(ObterPredicadoString(indice)),
                            doc => doc.id, ind => ind.id_documento, (doc, ind) => doc);
                            break;
                        case (int)Tipo.Inteiro:
                            querylinq = querylinq.Join(contexto.documento_indice.ToList().Where(ObterPredicadoInteiro(indice)),
                            doc => doc.id, ind => ind.id_documento, (doc, ind) => doc);
                            break;
                        case (int)Tipo.Data:
                            querylinq = querylinq.Join(
                            contexto.documento_indice.ToList().Where(ObterPredicadoData(indice)),
                            doc => doc.id, ind => ind.id_documento, (doc, ind) => doc);
                            break;
                    }
                }
            }

            quantidadeTotalDocumentos = querylinq.Count();

            return querylinq
                .OrderBy(a => a.id)
                .Skip(documentoBusca.resultado_inicial)
                .Take(documentoBusca.resultados_pagina);
        }
        catch (FaultException<DetalhesErro> e)
        {
            throw e;
        }
        catch (Exception e)
        {
            DetalhesErro tokenErro = new DetalhesErro(e, "Erro ao buscar a lista de documentos.");
            throw new FaultException<DetalhesErro>(tokenErro, new FaultReason(tokenErro.mensagemCurta));
        }
    }

    private Func<documento_indice, bool> ObterPredicadoString(IndiceBusca indice)
    {
        try
        {
            switch (indice.operador)
            {
                case "=":
                    return a => a.id_indice == indice.id && a.valor.ToLower() == indice.valor.ToLower();
                case "A*":
                    return a => a.id_indice == indice.id && a.valor.ToLower().StartsWith(indice.valor.ToLower());
                case "*A*":
                    return a => a.id_indice == indice.id && a.valor.ToLower().Contains(indice.valor.ToLower());
                case "<>":
                    return a => a.id_indice == indice.id && a.valor.ToLower() != indice.valor.ToLower();                    
                default:
                    return a => true;
            }
        }
        catch (FaultException<DetalhesErro> e)
        {
            throw e;
        }
        catch (Exception e)
        {
            DetalhesErro tokenErro = new DetalhesErro(e, "Erro ao obter o predicado.");
            throw new FaultException<DetalhesErro>(tokenErro, new FaultReason(tokenErro.mensagemCurta));
        }
    }

    private Func<documento_indice, bool> ObterPredicadoInteiro(IndiceBusca indice)
    {
        try
        {
            int valorInt = int.Parse(indice.valor);

            switch (indice.operador)
            {
                case "=":
                    return a => a.id_indice == indice.id && Convert.ToInt32(a.valor) == valorInt;                   
                case "<>":
                    return a => a.id_indice == indice.id && Convert.ToInt32(a.valor) != valorInt;
                case ">":
                    return a => a.id_indice == indice.id && Convert.ToInt32(a.valor) > valorInt;
                case "<":
                    return a => a.id_indice == indice.id && Convert.ToInt32(a.valor) < valorInt;
                case ">=":
                    return a => a.id_indice == indice.id && Convert.ToInt32(a.valor) >= valorInt;
                case "<=":
                    return a => a.id_indice == indice.id && Convert.ToInt32(a.valor) <= valorInt;
                default:
                    return a => true;
            }
        }
        catch (FaultException<DetalhesErro> e)
        {
            throw e;
        }
        catch (Exception e)
        {
            DetalhesErro tokenErro = new DetalhesErro(e, "Erro ao obter o predicado.");
            throw new FaultException<DetalhesErro>(tokenErro, new FaultReason(tokenErro.mensagemCurta));
        }
    }

    private Func<documento_indice, bool> ObterPredicadoData(IndiceBusca indice)
    {
        try
        {
            DateTime data = Convert.ToDateTime(indice.valor);

            switch (indice.operador)
            {
                case "=":
                    return a => a.id_indice == indice.id && Convert.ToDateTime(a.valor) == data;  
                case "<>":
                    return a => a.id_indice == indice.id && Convert.ToDateTime(a.valor) != data;
                case ">":
                    return a => a.id_indice == indice.id && Convert.ToDateTime(a.valor) > data;
                case "<":
                    return a => a.id_indice == indice.id && Convert.ToDateTime(a.valor) < data;
                case ">=":
                    return a => a.id_indice == indice.id && Convert.ToDateTime(a.valor) >= data;
                case "<=":
                    return a => a.id_indice == indice.id && Convert.ToDateTime(a.valor) <= data;
                default:
                    return a => true;
            }
        }
        catch (FaultException<DetalhesErro> e)
        {
            throw e;
        }
        catch (Exception e)
        {
            DetalhesErro tokenErro = new DetalhesErro(e, "Erro ao obter o predicado.");
            throw new FaultException<DetalhesErro>(tokenErro, new FaultReason(tokenErro.mensagemCurta));
        }
    }

希望这会有所帮助......