Test if a Collection of DataRow() HasChanges

Answered Test if a Collection of DataRow() HasChanges

  • jeudi 12 avril 2012 15:23
     
      A du code

    I use the Select method on my typed dataset to return an Array of DataRows.

    ' get settings for the DataGridView from the dataset and be sure to sort the returned rows by the display index
    Dim drs() As DataRow = Me.ds.NBB_DataGridViewSettings.Select(String.Format(Me.ds.NBB_DataGridViewSettings.DataGridViewNameColumn.ColumnName & " = '{0}'", lstDGVs(i)), _
    Me.ds.NBB_DataGridViewSettings.DisplayIndexColumn.ColumnName & " ASC")

    Is there a way to test if any of the DataRows in the Array have changes?

    I already know about DataSet.HasChanges method, but in my procedure I want to run some code on the DataRow() Array only if one of the rows have changes.  In my example below I get a subset of DataRows from my DataSet.  If only one DataRow in the DataSet has been modified my For Each...Loop will run 10 times.  

    For i As Integer = 0 To 10
    
    ' get settings for the DataGridView from the dataset and be sure to sort the returned rows by the display index
    Dim drs() As DataRow = Me.ds.NBB_DataGridViewSettings.Select(String.Format(Me.ds.NBB_DataGridViewSettings.DataGridViewNameColumn.ColumnName & " = '{0}'", lstDGVs(i)), _
                                                                                                Me.ds.NBB_DataGridViewSettings.DisplayIndexColumn.ColumnName & " ASC")
    
    ' if rows where added to or deleted from the dataset then the DisplayIndexes need to be reassigned
    If Me.ds.HasChanges Then
       For Each dr As DataRow In drs
          'do something
        Next dr
    End If
    
    Next i

    I only want it to run 1 time.  For example,

    For i As Integer = 0 To 10
    
    ' get settings for the DataGridView from the dataset and be sure to sort the returned rows by the display index
    Dim drs() As DataRow = Me.ds.NBB_DataGridViewSettings.Select(String.Format(Me.ds.NBB_DataGridViewSettings.DataGridViewNameColumn.ColumnName & " = '{0}'", lstDGVs(i)), _
                                                                                                Me.ds.NBB_DataGridViewSettings.DisplayIndexColumn.ColumnName & " ASC")
    
    ' if rows where added to or deleted from the dataset then the DisplayIndexes need to be reassigned
    If drs().HasChanges Then
       For Each dr As DataRow In drs
          'do something
        Next dr
    End If
    
    Next i

    Ryan

Toutes les réponses

  • vendredi 13 avril 2012 05:05
     
     

    Ryan,

    DataRows without Column information are useless. 

    A dataTable is a collection of Rows and Columns. 

    An Array of datarows does not have that column information, so why are you putting the rows in an array anyhow. It is strange and almost forever a resource spending slow action. Be aware that there is a DataRowCollection which has a reference to the original table.

    Therefore in my idea wrong to help you with something likewise jumping without shute from the Empire State Building.


    Success
    Cor


  • vendredi 13 avril 2012 06:11
     
     Traitée

    Hello Ryan,

    Please review DataView.RowStateFilter documentation for insight on getting changes where there are remarks within the documentation which once understood will get you on the proper path and if not read will cause you extra work. Best to run the example provided for RowStateFilter.


    KSG

    • Marqué comme réponse Ryan0827 vendredi 13 avril 2012 14:48
    •  
  • vendredi 13 avril 2012 13:19
     
     

    Cor,

    You asked, "An Array of datarows does not have that column information, so why are you putting the rows in an array anyhow?"  I need to get a subset of data from my main DataSet (Me.ds) so I use the Select method to find rows where a particular value is located in a particular column.  The Select method returns an Array of DataRows.  You can see that here, http://msdn.microsoft.com/en-us/library/y06xa2h1(v=vs.90).aspx.  I agree it would be preferred to work with DataTables that contain a reference to the original DataSet, but I'm not sure how to do that.  Do you know a way to obtain a subset DataTable that contains a reference to the original DataSet?

    Kevin,

    Thanks for pointing me to the DataView object.  I've always glanced over it, but never really took the time to read about it.  I think I can use this in some other parts of my application.  Learning something new everyday.  Try not to laugh to hard, I've only been doing this for almost a year.  :)

    Thanks, 


    Ryan



    • Modifié Ryan0827 vendredi 13 avril 2012 13:27
    • Modifié Ryan0827 vendredi 13 avril 2012 14:51
    •  
  • vendredi 13 avril 2012 13:55
     
     Traitée A du code

    Cor,

    You asked, "An Array of datarows does not have that column information, so why are you putting the rows in an array anyhow?"  I need to get a subset of data from my main DataSet (Me.ds) so I use the Select method to find rows where a particular value is located in a particular column.  The Select method returns an Array of DataRows.  You can see that here, http://msdn.microsoft.com/en-us/library/y06xa2h1(v=vs.90).aspx.  I agree it would be preferred to work with DataTables that contain a reference to the original DataSet, but I'm not sure how to do that.  Do you know a way to obtain a subset DataTable that contains a reference to the original DataSet?

    Hi Kevin,

    Thanks for the RowState idea.  I thought of this before I posted the question.  Since I'm working with DataRows() I'm not sure how I can use the DataView.RowStateFilter.  To use the RowState property I figured I would have to loop through all the rows in the array testing the RowState property of each DataRow.  I try to avoid looping in most cases, but maybe it would be fine in my case because I'm only looping through 20-50 rows.  I was hoping to find a more elegant way.  Is this what you are suggesting to do?

    Thanks, 


    Ryan

    Hi Ryan,

    If you want to visually see changes let's use a DataGridView for this example. Here dt is a DataTable which we want to see if there are any deleted rows and display them in a DataGridView. You could have other functions to do say added rows etc.

    DataGridView1.DataSource = DeletedRows(dt)

    Code for above

    Public Function DeletedRows(ByVal dt As DataTable) As DataView
        Dim dv As New DataView() With {.Table = dt}
        With dv
            .AllowNew = False
            .AllowDelete = True
            .RowStateFilter = DataViewRowState.Deleted
        End With
        Return dv
    End Function


    KSG

    • Marqué comme réponse Ryan0827 vendredi 13 avril 2012 16:56
    •  
  • vendredi 13 avril 2012 13:59
     
     

    If you want to see results of the code above in the IDE w/o a control such as a DataGridView place a breakpoint on the line which returns the DataView, select the magnifine image which shows the DataSet Visualizer as per the image below.


    KSG

  • vendredi 13 avril 2012 17:56
     
     

    Cor,

    You asked, "An Array of datarows does not have that column information, so why are you putting the rows in an array anyhow?"  I need to get a subset of data from my main DataSet (Me.ds) so I use the Select method to find rows where a particular value is located in a particular column.  The Select method returns an Array of DataRows.  You can see that here, http://msdn.microsoft.com/en-us/library/y06xa2h1(v=vs.90).aspx.  I agree it would be preferred to work with DataTables that contain a reference to the original DataSet, but I'm not sure how to do that.  Do you know a way to obtain a subset DataTable that contains a reference to the original DataSet?


    @Ryan,

    Sorry my mistake, so you see I've learned again something. I had always the idea it was a DataRowCollection which was returned from a Select.


    Success
    Cor

  • vendredi 13 avril 2012 22:02
     
     

    Cor,

    Now I understand why you thought I was crazy trying to work with an Array of DataRows :).  Out of curiosity, why would Microsoft want the Select method to return an Array of DataRows()?  Why not another DataTable that references the master DataSet?

    I’ve been reading about the DataView object Kevin suggested and seems like a powerful tool to work with subsets of data from my typed DataSet.  I did come across one issue though.  If I want to get a subset of data from my master DataSet and some of those rows contain errors the ToTable method doesn’t transfer the RowError property to my subset table.  Nor does it transfer the primary key.  Why?  Is there a better way to get a subset of data?

    Currently, I have to get my subset by using the dt = New DataView(table, filter, sort, rowstate).ToTable method.  Then I loop through each DataRow in dt, use the primary key value to find the matching DataRow in the master DataSet and setting the RowError property if it has one.  Seems kind of ridiculous.

    I’m getting much closer to deploying my first version of my application with a TON of help from this forum.  Big Thanks!


    Ryan