尝试添加行时,Row已经属于另一个表错误了吗?

时间:2017-08-09 07:56:33

标签: c# list datatable infragistics

我在下面尝试了这个解决方案:

This Row already belongs to another table error when trying to add rows?

我有一个包含597列和20行的数据表,并且正在尝试将数据导出到excel。但是,Excel的最大列数为256,因此我需要将源数据划分为3个数据表以使导出工作。

以下是我编写的代码。

var dtmasterdata = data.Tables[name];

for (int j = 1; j < datatableNumberCount; j++)
                        {
                            DataTable dt2 = new DataTable();
                            dt2.TableName = "Master_" + j;
                            dt2 = dtmasterdata.Copy();

                            foreach (DataColumn col in dtmasterdata.Columns)
                            {
                                DataColumn dtcol = new DataColumn();
                                dtcol = col;
                                dt2.Columns.Add(dtcol.ColumnName, dtcol.DataType);
                            }

                            for (int k = 0; k < dtmasterdata.Rows.Count; k++)
                            {
                                DataRow dr = dt2.NewRow();
                                dr = dtmasterdata.Rows[k];
                                dt2.ImportRow(dtmasterdata.Rows[k]);
                                //dt2.Rows.Add(dr.ItemArray);
                            }

之后我需要删除几个列,如下所示,我想创建3个数据表

foreach (DataColumn col in dtmasterdata.Columns)
                            {
                                if (j == 1)
                                {
                                    // condition 1
                                    if (col.Ordinal >= 255)
                                    {
                                        dt2.Columns.RemoveAt(col.Ordinal);
                                    }
                                }

                                if (j == 2)
                                {
                                    // condition 2.
                                    if (col.Ordinal < 255 || col.Ordinal >= 510)
                                    {
                                        dt2.Columns.RemoveAt(col.Ordinal);
                                    }
                                }

                                if (j == 3)
                                {
                                    // condition 3.
                                    if (col.Ordinal <= 510 || col.Ordinal >= 765)
                                    {
                                        dt2.Columns.Add(col);
                                    }
                                }
                            }

int worksheetNumber = 1;
                            string worksheetNameWithNumber = "Master Data";
                            if (worksheetNumber > 1)
                                worksheetNameWithNumber = String.Format("{0}_{1}", ws1, worksheetNumber.ToString());
                            Infragistics.Excel.Worksheet worksheet = wb.Worksheets.Add(worksheetNameWithNumber);
                            Infragistics.WebUI.UltraWebGrid.UltraWebGrid masterData1 = new Infragistics.WebUI.UltraWebGrid.UltraWebGrid("masterDataGrid");
                            masterData1.Browser = Infragistics.WebUI.UltraWebGrid.BrowserLevel.UpLevel;
                            masterData1.DataSource = dt2;
                            masterData1.DataMember = "Master_" + j;
                            masterData1.DisplayLayout.HeaderStyleDefault.Font.Bold = true;
                            masterData1.DisplayLayout.HeaderStyleDefault.Font.Name = "Arial";
                            masterData1.DisplayLayout.HeaderStyleDefault.Font.Size = FontUnit.Parse("10px");
                            masterData1.DisplayLayout.HeaderStyleDefault.BackColor = System.Drawing.Color.LightGray;
                            masterData1.DisplayLayout.RowStyleDefault.Font.Name = "Arial";
                            masterData1.DisplayLayout.RowStyleDefault.Font.Size = FontUnit.Parse("10px");
                            Infragistics.WebUI.UltraWebGrid.UltraGridBand masterBand1 = new Infragistics.WebUI.UltraWebGrid.UltraGridBand();
                            masterData1.Bands.Add(masterBand1);
                            dgResults.Controls.Add(masterData1);
                            masterData1.DataBind();
                            wb.ActiveWorksheet = worksheet;
                            this.ugWebGridExporter.Export(masterData1, worksheet);
                            worksheetNumber++;

2 个答案:

答案 0 :(得分:2)

您的错误是因为您尝试将列添加到已属于源数据表的数据表中。

dt2.Columns.Add(col);

您不能只遍历数据表的列并将它们添加到另一个数据表中。

我有一个解决方案,包括克隆源数据并删除你不需要的东西。

1,制作3个你需要的数据表克隆。下面是一个示例,我创建了自己的源表,包含596列。请注意,clone只接受数据表结构,没有数据!

var source597ColsTable = new DataTable("Source");

for (var i = 0; i <= 596; i++)
{
     source597ColsTable.Columns.Add(new DataColumn("Column" + i , typeof(string)));
}

DataRow newRow = source597ColsTable.NewRow();
source597ColsTable.Rows.Add(newRow);

var cols0To199Table = source597ColsTable.Clone();
var cols200To399Table = source597ColsTable.Clone();
var cols400To596Table = source597ColsTable.Clone();

接下来将源表中的所有行复制到克隆中。以下是一个简单的功能。

  private DataTable CopyRowsFromSource(DataTable sourceTable, DataTable destinationTable)
  {
     foreach (DataRow row in sourceTable.Rows)
     {
        destinationTable.Rows.Add(row.ItemArray);
     }

       return destinationTable;
    }

然后为每个表调用此函数。

    cols0To199Table = CopyRowsFromSource(source597ColsTable, cols0To199Table);
    cols200To399Table = CopyRowsFromSource(source597ColsTable, cols200To399Table);
    cols400To596Table = CopyRowsFromSource(source597ColsTable, cols400To596Table);

最后,删除数据表中的所有列以进行拆分。

 private DataTable RemoveColumns(DataTable table, int startCol, int endCol)
 {
       var colsToRemove = new List<DataColumn>();

       for (var colCount = startCol; colCount <= endCol; colCount++)
       {
            colsToRemove.Add(table.Columns[colCount]);
       }

       foreach (DataColumn col in colsToRemove)
       {
            table.Columns.Remove(col);
       }

       return table;
}

然后再次为每个克隆的表调用..

cols0To199Table = RemoveColumns(cols0To199Table, 200, 596); 

cols200To399Table = RemoveColumns(cols200To399Table, 0, 199); 
cols200To399Table = RemoveColumns(cols200To399Table, 200, 396); 

cols400To596Table = RemoveColumns(cols400To596Table, 0, 399); 

运行此项后,您将拥有3个数据表,列0-199,200-399和400-596。

希望有所帮助。

答案 1 :(得分:1)

我不确定是否真正了解了所有代码,但是要将列的子集复制到另一个数据表,DataView类中有一个名为ToTable的非常简单的方法,您可以在其中列出所需的列在新表中。作为额外的奖励,此方法还会复制原始表格的20行中的数据。

所以唯一困难的是将这些列列入方法。

您可以使用linq而不是DataColumn集合

继续这种方式
string[] firstCols = dtmasterdata.Columns
                         .Cast<DataColumn>()
                         .Take(255)
                         .Select(x => x.ColumnName).ToArray();
string[] secondCols = dtmasterdata.Columns
                          .Cast<DataColumn>()
                          .Skip(255)
                          .Take(255)
                          .Select(x => x.ColumnName).ToArray();
string[] thirdCols = dtmasterdata.Columns
                         .Cast<DataColumn>()
                         .Skip(510)
                         .Select(x => x.ColumnName).ToArray();

DataTable t1 = dtmasterdata.DefaultView.ToTable("Master_1", false, firstCols);
DataTable t2 = dtmasterdata.DefaultView.ToTable("Master_2", false, secondCols);
DataTable t3 = dtmasterdata.DefaultView.ToTable("Master_3", false, thirdCols);