【问题标题】:Row already belongs to another table error when trying to add rows?尝试添加行时,行已经属于另一个表错误?
【发布时间】:2017-08-09 07:56:33
【问题描述】:

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

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++;

【问题讨论】:

  • @kapli - 你看到我的回答了吗?

标签: c# list datatable infragistics


【解决方案1】:

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

dt2.Columns.Add(col);

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

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

第一,制作 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。

希望对您有所帮助。

【讨论】:

    【解决方案2】:

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

    所以唯一困难的是将这些列列出到方法中。

    您可以在 DataColumn 集合上使用 linq 以这种方式进行操作

    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);
    

    【讨论】:

      猜你喜欢
      • 2010-10-17
      • 2012-03-11
      • 1970-01-01
      • 1970-01-01
      • 2018-10-15
      • 2013-12-21
      • 2012-02-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多