none
Error con Repositorio Generico RRS feed

  • Pregunta

  • Hola desarrolladores, agradezco me puedan colaborar con este error ya que no logro entender el por que.

    No mapping to a relational type can be found for the CLR type 'List<string>'

    Eso me sucede en la siguiente parte

    public IEnumerable<Conceptos> ConsultaConceptos()
    {
          var concepVenta = _repo.GetAll<TiposV>().Select(x => x.Concepto).Distinct().ToList();
          var conceptos = _repo.Get<Conceptos>(x => concepVenta.Contains(x.Codigo)).ToList();
    
          return conceptos;
    }

    El error sucede cuando llego a conceptos y el metodo Get esta así

    IEnumerable<TEntity> Get<TEntity>(
                Expression<Func<TEntity, bool>> filter = null,
                Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
                string includeProperties = null,
                int? skip = null,
                int? take = null)
                where TEntity : class;

    entonces el recibe una expression cosa que hago, al parecer el lio es con el contains pero lo hago tal cual se hace normalmente en entityFramework.

    Logran detectar algún error? No tengo la menor idea que sucede :( agradezco su ayuda.

    lunes, 31 de diciembre de 2018 14:03

Respuestas

  • Prueba cambiando esto (agrega lo negrito)

     if (filter != null)
    {
           query = query.AsExpandable().Where(filter);
    }


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    debo hacer algun using? me dice que query no contiene una definicion para AsExpandible

    SI, esa extensión se encuentra en el paquete nuget 

    https://github.com/scottksmith95/LINQKit

    https://www.nuget.org/packages/LinqKit


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 2 de enero de 2019 21:57
    Moderador

Todas las respuestas

  • hola

    >>al parecer el lio es con el contains pero lo hago tal cual se hace normalmente en entityFramework

    si usas el Get() sin el Contains() resuelve de forma correcta ?

    >>No mapping to a relational type can be found for the CLR type 'List<string>'

    que funcion de EF implementas para definir el Get()? usas el Where

    Entity Framework List Contains in lambda

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    martes, 1 de enero de 2019 22:59
  • Hola. Creo que el error puede venir al usar concepVenta. Puedes mostrarnos la definición de las clases TiposV y Conceptos? Qué tipo corresponde a var concepVenta = xxxx?


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 2 de enero de 2019 7:40
    Moderador
  • Hola has probado hacer asi la consulta? 

          var conceptos = _repo.Get<Conceptos>(). Where(x => concepVenta.Contains(x.Codigo)). ToList();

    Lo más seguro es que no al usar el filters no pueda mapear correctamente la lista que Le pasas por parámetro (concepVenta) a un campo de base de datos. 

    Con otro tipo de filtros más simples no tienes problema? 


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos


    miércoles, 2 de enero de 2019 7:45
    Moderador
  • Hola has probado hacer asi la consulta? 

          var conceptos = _repo.Get<Conceptos>(). Where(x => concepVenta.Contains(x.Codigo)). ToList();

    Lo más seguro es que no al usar el filters no pueda mapear correctamente la lista que Le pasas por parámetro (concepVenta) a un campo de base de datos. 

    Con otro tipo de filtros más simples no tienes problema? 


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos


    Hola Sergio, Muchas gracias por responder, si lo hago como indicas funciona, pero entonces estaria consultando todos los conceptos y una vez consultados haría el filtro, la idea del metodo es pasar una expression para que cuando haga la query sea mas liviana, pues consulte directamente en la db la info que necesita con el where.

    Este es el metodo al que entra para arreglar la query

    protected virtual IQueryable<TEntity> GetQueryable<TEntity>(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = null,
            int? skip = null,
            int? take = null)
            where TEntity : class //, IEntity
            {
                includeProperties = includeProperties ?? string.Empty;
                IQueryable<TEntity> query = _context.Set<TEntity>();
    
                if (filter != null)
                {
                    query = query.Where(filter);
                }
    
                foreach (var includeProperty in includeProperties.Split
                    (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    query = query.Include(includeProperty);
                }
    
                if (orderBy != null)
                {
                    query = orderBy(query);
                }
    
                if (skip.HasValue)
                {
                    query = query.Skip(skip.Value);
                }
    
                if (take.HasValue)
                {
                    query = query.Take(take.Value);
                }
    
                return query;
            }

    como vez el hace el where y concatena el filter que es la expresion que trato de pasarle pero me da error :S

    Por eso es que no logro entender lo que sucede.

    miércoles, 2 de enero de 2019 13:11
  • hola

    >>al parecer el lio es con el contains pero lo hago tal cual se hace normalmente en entityFramework

    si usas el Get() sin el Contains() resuelve de forma correcta ?

    >>No mapping to a relational type can be found for the CLR type 'List<string>'

    que funcion de EF implementas para definir el Get()? usas el Where

    Entity Framework List Contains in lambda

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    Hola Leandro, gracias por responder

    >> si usas el Get() sin el Contains() resuelve de forma correcta ?

    Si, el puro get me retorna datos sin problema.

    >>que funcion de EF implementas para definir el Get()? usas el Where

    si, tengo el get, el método es el siguiente.

    protected virtual IQueryable<TEntity> GetQueryable<TEntity>(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = null,
            int? skip = null,
            int? take = null)
            where TEntity : class //, IEntity
            {
                includeProperties = includeProperties ?? string.Empty;
                IQueryable<TEntity> query = _context.Set<TEntity>();
    
                if (filter != null)
                {
                    query = query.Where(filter);
                }
    
                foreach (var includeProperty in includeProperties.Split
                    (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    query = query.Include(includeProperty);
                }
    
                if (orderBy != null)
                {
                    query = orderBy(query);
                }
    
                if (skip.HasValue)
                {
                    query = query.Skip(skip.Value);
                }
    
                if (take.HasValue)
                {
                    query = query.Take(take.Value);
                }
    
                return query;
            }
    en el filter el agrega el where y concatena el filter, en teoria debería funcionarme, no he logrado solucionar ese lio.

    miércoles, 2 de enero de 2019 13:14
  • Veo algo raro pero no entiendo el pq, si uno las 2 consultas si funciona sin problema, el lío esta cuando guardo en una variable la primera consulta.

    var conceptos = _repo.Get<Conceptos>().Where(x => (_repo.GetAll<TiposV>().Select(y => y.Concepto).Distinct()).Contains(x.Codigo)).ToList();

    Ese caso funciona sin problema, pero si guardo una parte en una variable para luego hacer el contains si me falla.

    var concepVenta = _repo.GetAll<TiposV>().Select(x => x.Concepto).Distinct().ToList();
    En teoría no debería ser lo mismo?

    miércoles, 2 de enero de 2019 13:22
  • Hola, NO son lo mismo. 

    No me he fijado antes, pero si haces esto

    var concepVenta = _repo.GetAll<TiposV>().Select(x => x.Concepto).Distinct();

    Quitando el ToList() lo que devuelve en concepVenta es un IQueryable<T>, que es lo que necesita el parámetro. Prueba y nos dices


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 2 de enero de 2019 13:29
    Moderador
  • hola

    lo que veo es que devuelves un IQueryable<> y esto hace que puedas seguir ejecutando la query aun fuera, que pasa si cambias a

    protected virtual List<TEntity> Get<TEntity>(

    no devuelvas un queriable

    Ademas no pongas todo en una linea es que complicado de entender

    var tipos = _repo.GetAll<TiposV>().Select(y => y.Concepto).Distinct();

    var conceptos = _repo.Get<Conceptos>().Where(x => tipos.Contains(x.Codigo)).ToList();

    recuerda que si usas Get<>() este devolvera una lista que cargara en memoria y sera alli dnde aplique el Where(), no sera una query a la db

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    miércoles, 2 de enero de 2019 13:32
  • Hola, NO son lo mismo. 

    No me he fijado antes, pero si haces esto

    var concepVenta = _repo.GetAll<TiposV>().Select(x => x.Concepto).Distinct();

    Quitando el ToList() lo que devuelve en concepVenta es un IQueryable<T>, que es lo que necesita el parámetro. Prueba y nos dices


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    Justo lo intente pero me da el mismo error.

    System.InvalidOperationException: 'No mapping to a relational type can be found for the CLR type 'IEnumerable<string>'.'
    

    miércoles, 2 de enero de 2019 14:03
  • hola

    lo que veo es que devuelves un IQueryable<> y esto hace que puedas seguir ejecutando la query aun fuera, que pasa si cambias a

    protected virtual List<TEntity> Get<TEntity>(

    no devuelvas un queriable

    Ademas no pongas todo en una linea es que complicado de entender

    var tipos = _repo.GetAll<TiposV>().Select(y => y.Concepto).Distinct();

    var conceptos = _repo.Get<Conceptos>().Where(x => tipos.Contains(x.Codigo)).ToList();

    recuerda que si usas Get<>() este devolvera una lista que cargara en memoria y sera alli dnde aplique el Where(), no sera una query a la db

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    Justo eso quisiera, tenerlo en 2 lineas separadas para que sea mas fácil de leer pero me da error.

    He intentado lo que me dices, cambio a List pero sigo teniendo el mismo error, lo unico que noto es que cuando paso esa variable es el error. Es muy raro, sera que debo hacer algún cast?

    Cuando miro la variable filter en el metodo llega asi.

    {x => value(ComercialWebApi.Services.ConceptosService+<>c__DisplayClass2_0).concepVenta.Contains(x.Codigo)}
    la lista se convierte en value, sera que no reconoce esa lista?

    • Editado CrissR miércoles, 2 de enero de 2019 14:13
    miércoles, 2 de enero de 2019 14:07
  • ¿Por qué Select? si x.Concepto es de tipo string, concepVenta será de tipo List<string>, cuando ejecutas el query con ToList(). El tipo string no contiene una propiedad Codigo...

    Ahí debería ir un where, en lugar del select.

    Hola miqui, el select es para seleccionar solo la propiedad concepto que es la que necesito, el lio lo tengo en la segunda query donde quiero sacar esos conceptos de la tabla.
    miércoles, 2 de enero de 2019 15:35
  • Hola. Puedes poner un punto de ruptura en tu metodo

    protected virtual IQueryable<TEntity> GetQueryable<TEntity>(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = null,
            int? skip = null,
            int? take = null)
            where TEntity : class //, IEntity

    Y ver en qué línea se produce la excepción?

    De todas formas comentar que ese Get devuelve un IQueryable y como tal luego puedes poner un where tal y como te puse en mi primera respuesta. Hasta que no haces un ToList no se ejecutariamos la consulta. 


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 2 de enero de 2019 19:07
    Moderador
  • Hola. Puedes poner un punto de ruptura en tu metodo

    protected virtual IQueryable<TEntity> GetQueryable<TEntity>(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = null,
            int? skip = null,
            int? take = null)
            where TEntity : class //, IEntity

    Y ver en qué línea se produce la excepción?

    De todas formas comentar que ese Get devuelve un IQueryable y como tal luego puedes poner un where tal y como te puse en mi primera respuesta. Hasta que no haces un ToList no se ejecutariamos la consulta. 


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    Hola sergio, así va la ejecución, llega a este método la consulta.

    public virtual IEnumerable<TEntity> Get<TEntity>(
                Expression<Func<TEntity, bool>> filter = null,
                Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
                string includeProperties = null,
                int? skip = null,
                int? take = null)
                where TEntity : class //, IEntity
            {
                return GetQueryable<TEntity>(filter, orderBy, includeProperties, skip, take).ToList();
            }

    Luego entra a GetQueryable

    protected virtual IQueryable<TEntity> GetQueryable<TEntity>(
            Expression<Func<TEntity, bool>> filter = null,
            Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
            string includeProperties = null,
            int? skip = null,
            int? take = null)
            where TEntity : class //, IEntity
            {
                includeProperties = includeProperties ?? string.Empty;
                IQueryable<TEntity> query = _context.Set<TEntity>();
    
                if (filter != null)
                {
                    query = query.Where(filter);
                }
    
                foreach (var includeProperty in includeProperties.Split
                    (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
                {
                    query = query.Include(includeProperty);
                }
    
                if (orderBy != null)
                {
                    query = orderBy(query);
                }
    
                if (skip.HasValue)
                {
                    query = query.Skip(skip.Value);
                }
    
                if (take.HasValue)
                {
                    query = query.Take(take.Value);
                }
    
                return query;
            }

    En filter lo examino y en debugview veo lo siguiente

    .Lambda #Lambda1<System.Func`2[ComercialWebApi.Models.Conceptos,System.Boolean]>(ComercialWebApi.Models.Conceptos $x) {
        .Call (.Constant<ComercialWebApi.Services.ConceptosService+<>c__DisplayClass2_0>(ComercialApi.Services.ConceptosService+<>c__DisplayClass2_0).Concepto).Contains($x.Codigo)
    }
    creo que el error esta al llegar al hacer 
    query = query.Where(filter)
    luego retorna el query y regresa al metodo anterior "Get" pero como hace ToList se revienta en esa parte pero creo que el error esta en el otro método que indico y ese parametro filter se me hace que llega un poco raro.

    miércoles, 2 de enero de 2019 19:26
  • Vale. Yo cambiaría el Contains por un Any

          var conceptos = _repo.Get<Conceptos>(x => concepVenta.Any(y => y == x.Concepto)).ToList();
    


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 2 de enero de 2019 19:39
    Moderador
  • Vale. Yo cambiaría el Contains por un Any

          var conceptos = _repo.Get<Conceptos>(x => concepVenta.Any(y => y == x.Concepto)).ToList();


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    Outch, sucede lo mismo, es muy extraño ese problema, lo loco del asunto es que si pongo la consulta en una sola linea funciona a la perfección, solo sucede el error si lo dejo en 2 lineas.
    miércoles, 2 de enero de 2019 20:27
  • Hola. Ponlo en una línea y haz depuración a ver qué diferencias encuentras. Yo lo veo raro. Y si fuera tu, si funciona en una línea déjalo asi. E investigaré qué ocurre con eso. 


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos


    miércoles, 2 de enero de 2019 20:45
    Moderador
  • Hola. Ponlo en una línea y haz depuración a ver qué diferencias encuentras. Yo lo veo raro. Y si fuera tu, si funciona en una línea déjalo asi. E investigaré qué ocurre con eso. 


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos


    por ahora lo tengo asi, solo que no puedo validarlo ya que dejando todo en una linea, no se llena el parametro filter  así que no lo pude validar.
    miércoles, 2 de enero de 2019 20:53
  • Prueba cambiando esto (agrega lo negrito)

     if (filter != null)
    {
           query = query.AsExpandable().Where(filter);
    }


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 2 de enero de 2019 20:59
    Moderador
  • Prueba cambiando esto (agrega lo negrito)

     if (filter != null)
    {
           query = query.AsExpandable().Where(filter);
    }


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    debo hacer algun using? me dice que query no contiene una definicion para AsExpandible
    miércoles, 2 de enero de 2019 21:13
  • Prueba cambiando esto (agrega lo negrito)

     if (filter != null)
    {
           query = query.AsExpandable().Where(filter);
    }


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    debo hacer algun using? me dice que query no contiene una definicion para AsExpandible

    SI, esa extensión se encuentra en el paquete nuget 

    https://github.com/scottksmith95/LINQKit

    https://www.nuget.org/packages/LinqKit


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 2 de enero de 2019 21:57
    Moderador