locked
way to duplicate (clone) a row in a datatable? RRS feed

  • Question

  • I've got a row with over 30 columns.  I have a process which needs to duplicate a row, update a few columns and create a new row.  There are different columns which need replacement at different times depending on user function.

    My first attempt was to 'Find' the original row, make changes and attempt to add that row.  e.g.

    myDS.InventoryRow originalInventoryRow = (myDS.InventoryRow) myDS.Inventory.FindByKey(this.PartNo.toString());

    <<... change required fields in 'originalInventoryRow', including the key value ..>>

    myDS.Tables["Inventory"].Rows.Add(originalInventoryRow);
    inventoryTableAdapter.Update(myDS.Inventory);

    The approach bombs out, exception saying that the row already exists, even tho I've changed the key field, in the origInventoryRow above and calling the 'Add' method.    Hate to write the code to copy field-by-field if there is an easier way.   

    Thanks for any opinions, comments, directions.

    JS

     

    Friday, December 30, 2005 2:19 AM

Answers

  • Hi JS,

    I know you may have workaround this as you've posted this for a long time. However, I'm also looking for the above problem and found the following solution.

    For a datarow, you can use the ItemArray to retrieve the datarow columns as an array. After that, you can create new datarow of the same type and then reassign the ItemArray back to the new datarow. I believe this is the simplest way to clone a datarow in case a Clone function is not available.

    Monday, May 22, 2006 3:02 AM
  •     The ImportRow method might also prove helpful.

    Thursday, June 1, 2006 1:01 AM
  •  

    ImportRow is designed for this kind of scenarios only, so check it out.  I have used it manytimes for such requirements.

    Monday, June 19, 2006 5:34 AM

All replies

  • Here originalInventoryRow is a reference to the original row (no pun intended). When you try to add it to the table in myDS.Tables["Inventory"].Rows.Add(originalInventoryRow);
    you are actually trying to add the row which already exists in the database (
    originalInventoryRow points to the old datarow). So I'm afraid you'll have to create a new datarow and copy into it the fields from the old row.
    Friday, December 30, 2005 9:20 AM
  • Thanks Yan.  I was afraid of that.  I've created my own method in the meantime, but hate to maintain it if there was another way.

    JS

    Friday, December 30, 2005 6:43 PM
  • Hi JS,

    I know you may have workaround this as you've posted this for a long time. However, I'm also looking for the above problem and found the following solution.

    For a datarow, you can use the ItemArray to retrieve the datarow columns as an array. After that, you can create new datarow of the same type and then reassign the ItemArray back to the new datarow. I believe this is the simplest way to clone a datarow in case a Clone function is not available.

    Monday, May 22, 2006 3:02 AM
  •     The ImportRow method might also prove helpful.

    Thursday, June 1, 2006 1:01 AM
  • this works...

    Dim dtTemp As DataTable = <method to fill datatable>
    Dim drOrig As DataRow
    Dim dcTemp As DataColumn
    Dim intRowCount As Integer = dtTemp.Rows.Count - 1 'get the row count

    'loop through the original rows  
    For intCount As Integer = 0 To intRowCount 
        Dim drRev As DataRow
       
        'get an "original" row
        drOrig = dtTemp.Rows(intCount)     
       
        'push the setup from the datatable to a NewRow
        drRev = dtTemp.NewRow              

        'Set the new rows values to the orig rows values                                         
        drRev.ItemArray = drOrig.ItemArray 

        'change the fields you want to change
        drRev("InvType") = "ARV"           
        drRev("Qty") = (CType(drOrig("Qty"), Integer) * -1)
        drRev("TotalSquareFt") = (CType(drOrig("TotalSquareFt"), Double) * -1)
        drRev("Amount") = (CType(drOrig("Amount"), Integer) * -1)

        'push the new row into the datatable
        dtTemp.Rows.Add(drRev)              
    Next

    Friday, June 16, 2006 7:06 PM
  •  

    ImportRow is designed for this kind of scenarios only, so check it out.  I have used it manytimes for such requirements.

    Monday, June 19, 2006 5:34 AM
  • Hi, I'm posting 5 years later  but this code can be useful:

      Private Function CloneRow(ByVal table As DataTable, ByVal clonedRow As DataRow) As DataRow
        Dim PrimaryKeys As ArrayList = New ArrayList(table.PrimaryKey)
        Dim newRow As DataRow = table.NewRow()
    
        For Each col As DataColumn In table.Columns
          If Not PrimaryKeys.Contains(col) Then
            newRow(col.ColumnName) = clonedRow(col.ColumnName)
          End If
        Next
        Return newRow
      End Function
    

    It clone all rows exept keys. You have to assign them after.

    • Proposed as answer by DJWoods Tuesday, September 27, 2011 2:47 PM
    Thursday, August 25, 2011 1:53 PM
  • Here's a tiny example of what is meant by "use ImportRow":

      result.Tables[0].ImportRow(result.Tables[0].Rows[0])

    Not sure how this handles keys.

    Thursday, November 10, 2011 9:31 PM