2016-02-04 67 views
0

我试图从Linq使用DataTable获取一些数据,但它给了我以下错误: 指定的转换无效。linq转换错误

首先,我使用这个粘贴从Excel中复制细胞的DataGridView

 private void btnExcel_Click(object sender, EventArgs e) 
    { 

     dataGridView1.Columns.Clear(); 
     dataGridView1.Columns.Add("Column1", "Column1"); 
     dataGridView1.Columns.Add("Column2", "Column2"); 
     dataGridView1.Columns.Add("Column3", "Column3"); 
     dataGridView1.Columns.Add("Column4", "Column4"); 
     dataGridView1.Columns.Add("Column5", "Column5"); 
     dataGridView1.Columns.Add("Column6", "Column6"); 
     dataGridView1.Columns.Add("Column7", "Column7"); 
     dataGridView1.Columns.Add("Column8", "Column8"); 
     dataGridView1.Columns.Add("Column9", "Column9"); 
     dataGridView1.Columns.Add("Column10", "Column10"); 
     dataGridView1.Columns.Add("Column11", "Column11"); 
     dataGridView1.Columns.Add("Column12", "Column12"); 
     dataGridView1.Columns.Add("Column13", "Column13"); 

     DataObject o = (DataObject)Clipboard.GetDataObject(); 
     if (o.GetDataPresent(DataFormats.UnicodeText)) 
     { 
      if (dataGridView1.RowCount > 0) 
       dataGridView1.Rows.Clear(); 

      string[] pastedRows = Regex.Split(o.GetData(DataFormats.UnicodeText).ToString().TrimEnd("\r\n".ToCharArray()), "\r\n"); 
      int j = 0; 
      foreach (string pastedRow in pastedRows) 
      { 
       string[] pastedRowCells = pastedRow.Split(new char[] { '\t' }); 

       dataGridView1.Rows.Add(); 
       int myRowIndex = dataGridView1.Rows.Count - 1; 

       using (DataGridViewRow myDataGridViewRow = dataGridView1.Rows[j]) 
       { 
        for (int i = 0; i < pastedRowCells.Length; i++) 
         myDataGridViewRow.Cells[i].Value = pastedRowCells[i]; 
        this.dataGridView1.AutoResizeColumns(); 

       } 
       j++; 
      } 
     } 




    } 

然后,我用这个方法,使用后的datagridview转换为数据表

 private DataTable GetDataTableFromDGV(DataGridView dgv) 
    { 
     var dt = new DataTable(); 
     foreach (DataGridViewColumn column in dgv.Columns) 
     { 
      if (column.Visible) 
      { 
       // You could potentially name the column based on the DGV column name (beware of dupes) 
       // or assign a type based on the data type of the data bound to this DGV column. 
       dt.Columns.Add(); 
      } 
     } 

     object[] cellValues = new object[dgv.Columns.Count]; 
     foreach (DataGridViewRow row in dgv.Rows) 
     { 
      for (int i = 0; i < row.Cells.Count; i++) 
      { 
       cellValues[i] = row.Cells[i].Value; 
      } 
      dt.Rows.Add(cellValues); 
     } 

     return dt; 
    } 

此linq查询获取数据并将其显示到datagridview2

  DataTable dt = GetDataTableFromDGV(dataGridView1); 

     //foreach (DataColumn c in dt.Columns) 
     //{ 
     // MessageBox.Show(c.ColumnName); 
     //} 

     var groupedData = from b in dt.AsEnumerable() 
          group b by b.Field<int>("Column2") into g 
          select new 
          { 
           column2 = g.Key, 
           column13 = g.Sum(x => x.Field<decimal>("Column13")) 
          }; 

     foreach (var result in groupedData) 
     { 
      dataGridView2.Rows.Add(result); 
     } 

它会抛出一个“Spe指定的演员表无效。“

基本上我想要的是在下面的图片显示:

pic

+0

在该线在抛出异常? – Gusman

+0

用'dt.AsEnumerable()'通过它自己来尝试以下内容 'var someValue = Convert.ToDecimal(dt.AsEnumerable()。Sum(x => Convert.ToDecimal(x [“Column13”])))'' – MethodMan

回答

0

你从来就不是一个类型分配给任何你展示DataColumns的,所以他们将有string默认的数据类型,并调用Field<int>Field<decimal>将抛出无效的转换异常。

要么创建数据表时指定相应的类型的列或分析字符串值:

var groupedData = from b in dt.AsEnumerable() 
         group b by int.Parse(b.Field<string>("Column2")) into g 
         select new 
         { 
          column2 = g.Key, 
          column13 = g.Sum(x => decimal.Parse(x.Field<string>("Column13"))) 
         };