none
Error en consulta LINQ utilizando CopyToDataTable RRS feed

  • Pregunta

  •  

     

    Cordial saludo.

    Ésta pregunta surgió en otro foro anterior ( http://social.msdn.microsoft.com/Forums/es-ES/vcses/thread/ce88898c-0af4-4afa-85f4-2ae1966d6c6a).

    El problema es que necesito obtener varios campos de un DataTable original, y a su vez ordenarlos y agruparlos por uno de esos campos. Intenté implementar lo que Leandro Tuttini propone en su foro: http://ltuttini.blogspot.com/2010/05/linq-dataset-agrupar-y-totalizar.html pero me sale un error en el query que aparece a continuación:

     

     

     IEnumerable<IGrouping<String, DataRow>> query2 = from item in tabla.AsEnumerable()
            group item by item[tabla.Columns[14]].ToString() into r
            orderby tabla.Columns[14].ToString()
            select new ManejadorBD
            {
            NombreOficina = r.ElementAt(0).ItemArray[14].ToString(),
            DireccionOficina = r.ElementAt(12).ItemArray[0].ToString(),
            Ciudad = r.ElementAt(13).ItemArray[0].ToString(),
            Producto = r.ElementAt(2).ItemArray[0].ToString(),
            NumeroPedido = r.ElementAt(1).ItemArray[0].ToString(),
            Entrega = r.ElementAt(36).ItemArray[0].ToString(),
            CantidadPedido = Int32.Parse(r.ElementAt(6).ItemArray[0].ToString()),
            NombreArchivo = r.ElementAt(16).ItemArray[0].ToString()
            };
    
    
      dtPedidosPorOficina = manejadorBD.GetInfoEtiquetas(cbCliente.SelectedText, query2);
    

    La asignación de las variables dentro del Select creo que está mal, la verdad no sé cómo hacer referencia a los campos del dataTable original.

     

    Error    1    Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<EtiquetasFacturacionModelo.ManejadorBD>' to 'System.Collections.Generic.IEnumerable<System.Linq.IGrouping<string,System.Data.DataRow>>'. An explicit conversion exists (are you missing a cast?)  

     

    Y en la clase ManejadorBD tengo:

     

     

     /// <summary>
     /// Código adaptado de http://ltuttini.blogspot.com/2010/05/linq-dataset-agrupar-y-totalizar.html 
     /// </summary> 
     public DataTable GetInfoEtiquetas(String cliente, IEnumerable<IGrouping<String, DataRow>> datos) 
     {
      DataTable dt = new DataTable();
      dt.Columns.Add("NombreOficina");
      dt.Columns.Add("DireccionOficina");
      dt.Columns.Add("Ciudad");
      dt.Columns.Add("Producto");
      dt.Columns.Add("NumeroPedido");
      dt.Columns.Add("Entrega");  
      dt.Columns.Add("CantidadPedido");
      dt.Columns.Add("NombreArchivo");
    
      foreach (IGrouping<String, DataRow> item in datos) 
      {
      DataRow row = dt.NewRow();
      row["NombreOficina"] = item.ElementAt(0);
      row["DireccionOficina"] = item.ElementAt(1);
      row["Ciudad"] = item.ElementAt(2);
      row["Producto"] = item.ElementAt(3);
      row["NumeroPedido"] = item.ElementAt(4);
      row["Entrega"] = item.ElementAt(5);
      row["CantidadPedido"] = item.ElementAt(6);
      row["NombreArchivo"] = item.ElementAt(7);
    
      dt.Rows.Add(row);
      }
    
      return dt;
     }
    

     

    Les agradezco por la colaboración!

    P.D.: Hay alguna librería que haya que importar para que aparezca el método CopyToDataTable()? cuando utilizo un var query y dentro de éste hago la consulta Linq, luego no me aparece el método query.CopyToDataTable.... Alguna idea?

    lunes, 25 de julio de 2011 14:39

Respuestas

  • Hola Andrés:

     

     

     

    Te paso una sentencia que crea un datatable con campos id,zona,importe. la sentencia suma los importes por id y zona:

     

     

     

    DataTable t = new DataTable();

                t.Columns.Add("id", typeof(int));

                t.Columns.Add("zona", typeof(int));

                t.Columns.Add("cantidad", typeof(Decimal));

     

                t.Rows.Add(new object[] { 1 ,2,10M});

                t.Rows.Add(new object[] { 1 ,2,20M});

     

                t.Rows.Add(new object[] { 2 ,1,10M});

                t.Rows.Add(new object[] { 2 ,2,20M});

     

                t.Rows.Add(new object[] { 3 ,1,10M});

                t.Rows.Add(new object[] { 3, 1,20M});

     

     

     

     

     

     

                var a = from b in t.AsEnumerable()

                        where b.Field<int>("id") > 1  

                        orderby b.Field<int>("id")

                        group b by new{id=b.Field<int>("id"),zona=b.Field<int>("zona")} into r

                        select r;            

     

                foreach(var group in a)

                {

     

                   decimal Total =  group.Sum((fila) => { return fila.Field<decimal>("cantidad"); });

     

                }

    En group.Key tienes disponibles el id y la zona. Si quieres acceder a ellos solamente tienes que escribir group.Key.id,group.Key.zona. dentro del foreach.

     

     

     

    2. CopyToDataTable().

     

     

     

    Este metodo solamente está disponible para IEnumerable de DataRow, cuando utilizas group no puedes, pero si dentro de foreach. Te paso una sentencia para que veas donde puedes  utilizar CopyToDataTable().

     

      foreach(var group in a)

                {

                   group.CopytoDataTable(<NuevaTabla>);

                   decimal Total =  group.Sum((fila) => { return fila.Field<decimal>("cantidad"); });

     

                }

    o bien

     var query = from b in t.AsEnumerable()

                        select b;

    query.CopyToDataTable(<NuevaTabla>);

     

    Saludos,


    phurtado
    lunes, 25 de julio de 2011 16:33
    Moderador