none
Números Consecutivos con linq RRS feed

  • Pregunta

  • Buenas estimados,

    Tengo este código y quisiera saber como hacer numero correlativo  no tengo mucha idea

    (from a1 in cnx.Area
                      join a2 in cnx.Area on a1.idareasuperior equals a2.idarea into  a3
                      from a4 in a3.DefaultIfEmpty()
                      where a1.flgeli=="0"
                     
                      select new AreaReporte()
                      {
                          Num=(PONER CODIGO CORRELATIVO),
                          NombreArea=a1.nombre,
                          NombreAreaSuperior=(a4==null) ? "" : a4.nombre
                      }).ToList();


    Jorge Alvarado Clemente. Programador Junior

    lunes, 14 de septiembre de 2015 17:18

Respuestas

  • no me deja poner el ++ de signo

    Con una sentencia de LINQ-to-objects sí que te dejaría, pero con LINQ-to-SQL el sistema intenta traducirlo a una sentencia SQL y no sabe traducir el ++, por lo que da error. El remedio consiste en materializar la primero la consulta con el ToList que ya tienes al final, y después sobre el resultado (que ya es un objeto en memoria) aplicar el LINQ-to-objects para incluir el secuencial:

    int correlativo = 0;
    var resultado = from a1 in cnx.Area
     join a2 in cnx.Area on a1.idareasuperior equals a2.idarea into  a3
     from a4 in a3.DefaultIfEmpty()
     where a1.flgeli=="0"                 
     select new
     {
        NombreArea=a1.nombre,
        NombreAreaSuperior=(a4==null) ? "" : a4.nombre
     }).ToList().Select(r=>new AreaReporte()
        {
          Num = ++correlativo,
          NombreArea=r.NombreArea,
          NombreAreaSuperior=r.NombreAreaSuperior
        }).ToList();

    martes, 15 de septiembre de 2015 5:01

Todas las respuestas

  • ¿Qué alcance tiene que tener el número correlativo? ¿Es local a la lista que se está generando en memoria? En ese caso, basta declarer una variable fuera del "from" e irla incrementando:

    int correlativo = 0;
    (from a1 in cnx.Area
                       join a2 in cnx.Area on a1.idareasuperior equals a2.idarea into  a3
                       from a4 in a3.DefaultIfEmpty()
                       where a1.flgeli=="0"
                      
                       select new AreaReporte()
                       {
                           Num = ++correlativo,
                           NombreArea=a1.nombre,
                           NombreAreaSuperior=(a4==null) ? "" : a4.nombre
                       }).ToList(); 

    lunes, 14 de septiembre de 2015 18:00
  • Eso he tratado de hacer y no me deja poner el ++ de signo al final lo puse en el mismo reporte en el rdlc que estoy ahciendo pero igual quisera saber como ahcerlo en linq

    Jorge Alvarado Clemente. Programador Junior

    lunes, 14 de septiembre de 2015 23:00
  • hola

    de casualidad usas entity framework o algun otro orm ?

    porque puedes que si pones el ++ en ese linq no este pudiendo convertir este a sql

    podrias armar la query simple y lusto de que esta ejecute usar

    List<AreaReporte> result = (from a1 in cnx.Area .... ).ToList();
    
    int num= 0;
    result.ForEach(x=> x.Num = ++num);

    pero como veras se tuvo que ejecutar la query linq yluego generas el secuencial

    por eso es importante el ToList()

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    martes, 15 de septiembre de 2015 1:02
  • no me deja poner el ++ de signo

    Con una sentencia de LINQ-to-objects sí que te dejaría, pero con LINQ-to-SQL el sistema intenta traducirlo a una sentencia SQL y no sabe traducir el ++, por lo que da error. El remedio consiste en materializar la primero la consulta con el ToList que ya tienes al final, y después sobre el resultado (que ya es un objeto en memoria) aplicar el LINQ-to-objects para incluir el secuencial:

    int correlativo = 0;
    var resultado = from a1 in cnx.Area
     join a2 in cnx.Area on a1.idareasuperior equals a2.idarea into  a3
     from a4 in a3.DefaultIfEmpty()
     where a1.flgeli=="0"                 
     select new
     {
        NombreArea=a1.nombre,
        NombreAreaSuperior=(a4==null) ? "" : a4.nombre
     }).ToList().Select(r=>new AreaReporte()
        {
          Num = ++correlativo,
          NombreArea=r.NombreArea,
          NombreAreaSuperior=r.NombreAreaSuperior
        }).ToList();

    martes, 15 de septiembre de 2015 5:01
  • Muchas gracias una pregunta más(aunque sonara a básica seguro) como en si se que linq estoy usando o que lo hace especial o único en si a cada uno 

    Jorge Alvarado Clemente. Programador Junior

    martes, 15 de septiembre de 2015 21:29
  • si estoy usando entity framework

    Jorge Alvarado Clemente. Programador Junior

    martes, 15 de septiembre de 2015 22:11
  • [...] como en si se que linq estoy usando o que lo hace especial o único en si a cada uno
    Lo sabes por el objeto que escribes detras del "in", por ejemplo, ...from a1 in cnx.Area. El compilador toma tu sentencia Linq y la traduce en varias llamadas a funciones sobre ese objeto, tales como Where(), OrederBy() o Select(). Según cómo se implementen dichas funciones dentro de ese objeto estás usando una u otra variante de Linq. En el caso de que el objeto sea un List, esas funciones no existen dentro del List, pero si existen dentro de unos extensores de la interfaz IEnumerable (que List implementa) los cuales se traen dentro del alcance de la sentencia gracias al "using System.Linq" que hay al principio del fuente. Cuando se usan estos extensores de IEnumerable, se dice que estamos usando Linq to Objects. Similarmente, cuando usas un DbSet dentro de un DbContext u ObjectContext (como el cnx.Area) entran en juego otros métodos Where(), OrederBy(), Select(), etc., que Entity Framework implementa sobre las clases madre de esos objetos. En este caso se dice que usas Linq-to-Entities (no Linq-to-Sql como yo te puse arriba, éste último es el que se aplica cuando usas un .dbml en lugar de EF).
    miércoles, 16 de septiembre de 2015 5:10
  • Osea si yo para poder usar tu codigo deberi llamar a la entidad que crea el entity framework mas no anteponiendole el in y haciendo que este vaya a una base de datos ya que con eso estas expresandole asi, pero con object no haria que esos datos esten en duros y no jalando desde la base de datos

    Jorge Alvarado Clemente. Programador Junior

    miércoles, 16 de septiembre de 2015 22:53
  • Osea si yo para poder usar tu codigo deberi llamar a la entidad que crea el entity framework mas no anteponiendole el in

    No, eso no tiene nada que ver. La frase que tiene el "in" es solo "azúcar sintáctico" para el compilador, de forma que quede bonito al escribirlo. Pero el compilador lo traduce a una serie de llamadas a métodos del objeto. En la sentencia que yo te escribí, la primera parte la tenías ya escrita en la forma "larga" y la segunda te la escribí yo en la forma "corta" porque es un poco más engorroso escribir una "larga" conecte con otra "larga" (típicamente lo haríamos con una variable intermedia). Pero perfectamente podríamos haber escrito las dos en forma "corta" y daría igual, eso no influye en que una sea de linq-to-objects y la otra de linq-to entities. Únicamente la clase del objeto que se usa como punto de partida (en ambos casos) es la que determina la modalidad aplicada.
    jueves, 17 de septiembre de 2015 5:36