none
TableAdapter.Update causes DataTable.RowChanging to fire for all changed rows RRS feed

  • Question

  • I have a Dataset with a DataTable for which I have extended functionalities by using the partial class file. Concretely I'm doing additional processing each time a row on the DataTable has been changed. All is good but when I try to save changes to the database with the TableAdapter.Update method, it causes the RowChanging event to fire again for all the changed rows since the last fill, which causes the additional processing to be done twice. The actual scenario is this:

    I have two tables "REMPLISSAGE" (order) and "LIGNE_ENTREE_REMPLISSAGE" (order line) where the order table has a column "final".

    1. I change a row value on ""LIGNE_ENTREE_REMPLISSAGE" using a control
    2. The RowChanging event fires and causes the additional processing to be done (I set the flag "final" to false). In this case, DataRowVersion.Current and DataRowVersion.Proposed are different.
    3. The user manually sets "final" to true meaning that the order is no more a draft.
    4. I call TableAdapterManager.UpdateAll to commit changes to the database
    5. OrderLineTableAdapter.Update causes the RowChanging event to fire again, which causes the additional processing to be done and hence overriding the user confirmation of the order. In this case all DataRowVersions are the same.

    This is the call stack of the 5th point, which I don't want it to happen:

    >	Distramed.exe!Distramed.distramedDataSet.LIGNE_ENTREE_REMPLISSAGEDataTable.ligne_entree_remplissageDataTable_ligne_entree_remplissageRowChanging(Object sender, Distramed.distramedDataSet.LIGNE_ENTREE_REMPLISSAGERowChangeEvent e) Line 496	Basic
     	Distramed.exe!Distramed.distramedDataSet.LIGNE_ENTREE_REMPLISSAGEDataTable.OnRowChanging(System.Data.DataRowChangeEventArgs e) Line 5024 + 0x94 bytes	Basic
     	System.Data.dll!System.Data.DataTable.OnRowChanging(System.Data.DataRowChangeEventArgs args, System.Data.DataRow eRow, System.Data.DataRowAction eAction) + 0x56 bytes	
     	System.Data.dll!System.Data.DataTable.RaiseRowChanging(System.Data.DataRowChangeEventArgs args, System.Data.DataRow eRow, System.Data.DataRowAction eAction) + 0x93 bytes	
     	System.Data.dll!System.Data.DataTable.RaiseRowChanging(System.Data.DataRowChangeEventArgs args, System.Data.DataRow eRow, System.Data.DataRowAction eAction, bool fireEvent) + 0xb8 bytes	
     	System.Data.dll!System.Data.DataTable.SetNewRecordWorker(System.Data.DataRow row, int proposedRecord, System.Data.DataRowAction action, bool isInMerge, bool suppressEnsurePropertyChanged, int position, bool fireEvent, out System.Exception deferredException) + 0x8c bytes	
     	System.Data.dll!System.Data.DataTable.SetNewRecord(System.Data.DataRow row, int proposedRecord, System.Data.DataRowAction action, bool isInMerge, bool fireEvent, bool suppressEnsurePropertyChanged) + 0x2e bytes	
     	System.Data.dll!System.Data.DataRow.EndEdit() + 0x62 bytes	
     	System.Data.dll!System.Data.DataRow.this[System.Data.DataColumn].set(System.Data.DataColumn column, object value) + 0x14e bytes	
     	System.Data.dll!System.Data.ProviderBase.SchemaMapping.ApplyToDataRow(System.Data.DataRow dataRow) + 0xff bytes	
     	System.Data.dll!System.Data.Common.DbDataAdapter.UpdateRowExecute(System.Data.Common.RowUpdatedEventArgs rowUpdatedEvent, System.Data.IDbCommand dataCommand, System.Data.StatementType cmdIndex) + 0x13d bytes	
     	System.Data.dll!System.Data.Common.DbDataAdapter.Update(System.Data.DataRow[] dataRows, System.Data.Common.DataTableMapping tableMapping) + 0x81c bytes	
     	System.Data.dll!System.Data.Common.DbDataAdapter.Update(System.Data.DataRow[] dataRows) + 0x7a bytes	
     	Distramed.exe!Distramed.distramedDataSetTableAdapters.LIGNE_ENTREE_REMPLISSAGETableAdapter.Update(System.Data.DataRow() dataRows) Line 22638 + 0x1a bytes	Basic
     	Distramed.exe!Distramed.distramedDataSetTableAdapters.TableAdapterManager.UpdateUpdatedRows(Distramed.distramedDataSet dataSet, System.Collections.Generic.List(Of System.Data.DataRow) allChangedRows, System.Collections.Generic.List(Of System.Data.DataRow) allAddedRows) Line 33242 + 0x1d bytes	Basic
     	Distramed.exe!Distramed.distramedDataSetTableAdapters.TableAdapterManager.UpdateAll(Distramed.distramedDataSet dataSet) Line 34454 + 0x1c bytes	Basic

    The only solution I've found is to compare all colmun values for the two versions DataRowVersion.Current and DataRowVersion.Proposed to see if there has been actual changes or it's just a dummy call, but that seems a little bit tedious.

    Edit: I forgot to mention that I only do the processing if e.Action=Change on the event handler. Also I'm using VB.NET 2012 with SQL Server Express 2012.


    Sunday, November 25, 2012 12:20 PM

Answers

  • When a TableAdapter.Update() has completed, the DataSet/DataTable.AcceptChanges() method is called. It is the .AcceptChanges() that fires the RowChanged event. However, there is an easy way to test this in your RowChanging event handler. Only do your processing if e.Action is not equal to DataRowAction.Commit (e being the DataRowChangeEventArgs) .

     

    ~~Bonnie Berent DeWitt [C# MVP]

    geek-goddess-bonnie.blogspot.com

    • Marked as answer by Alexander Sun Friday, December 7, 2012 1:41 AM
    Sunday, November 25, 2012 4:58 PM