상속: System.EventArgs
예제 #1
0
			protected override void OnRowUpdated (RowUpdatedEventArgs value)
			{
				throw new NotImplementedException ();
			}
예제 #2
0
    /// <summary>
    /// Raised by DbDataAdapter after a row is updated
    /// </summary>
    /// <param name="value">The event's specifics</param>
    protected override void OnRowUpdated(RowUpdatedEventArgs value)
    {
      EventHandler<RowUpdatedEventArgs> handler = base.Events[_updatedEventPH] as EventHandler<RowUpdatedEventArgs>;

      if (handler != null)
        handler(this, value);
    }
        /// <summary>
        /// Raised by the underlying DbDataAdapter after a row has been
        //updated
        /// </summary>
        protected override void OnRowUpdated(RowUpdatedEventArgs value)
        {
            EventHandler<RowUpdatedEventArgs> handler =
					Events[EventRowUpdated]as
					EventHandler<RowUpdatedEventArgs>;
            if (handler != null)
                handler(this, (RowUpdatedEventArgs) value);
        }
예제 #4
0
 /// <summary>
 /// Overridden. Raises the RowUpdated event.
 /// </summary>
 /// <param name="value">A MySqlRowUpdatedEventArgs that contains the event data. </param>
 override protected void OnRowUpdated(RowUpdatedEventArgs value)
 {
   if (RowUpdated != null)
     RowUpdated(this, (value as MySqlRowUpdatedEventArgs));
 }
		protected override void OnRowUpdated (RowUpdatedEventArgs value) 
		{
         		SybaseRowUpdatedEventHandler handler = (SybaseRowUpdatedEventHandler) Events[EventRowUpdated];
			if ((handler != null) && (value is SybaseRowUpdatedEventArgs))
            			handler(this, (SybaseRowUpdatedEventArgs) value);
		}
예제 #6
0
 protected override void OnRowUpdated(RowUpdatedEventArgs value)
 {
     CrmDataAdapterRowUpdatedEventHandler handler = (CrmDataAdapterRowUpdatedEventHandler)Events[EventRowUpdated];
     if ((null != handler) && (value is CrmDataAdapterRowUpdatedEventArgs))
     {
         handler(this, (CrmDataAdapterRowUpdatedEventArgs)value);
     }
 }
예제 #7
0
 protected override void OnRowUpdated(
 RowUpdatedEventArgs value)
 {
 }
예제 #8
0
        private int UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, int commandCount)
        {
            Debug.Assert(null != batchCommands, "null batchCommands?");
            Exception errors = rowUpdatedEvent.Errors;
            if (null == errors)
            {
                // user changed status to ErrorsOccured without supplying an exception message
                errors = ADP.RowUpdatedErrors();
                rowUpdatedEvent.Errors = errors;
            }

            int affected = 0;
            bool done = false;
            string message = errors.Message;

            for (int i = 0; i < commandCount; i++)
            {
                DataRow row = batchCommands[i]._row;
                Debug.Assert(null != row, "null dataRow?");

                if (null != batchCommands[i]._errors)
                { // will exist if 0 == RecordsAffected
                    string rowMsg = batchCommands[i]._errors.Message;
                    if (string.IsNullOrEmpty(rowMsg))
                    {
                        rowMsg = message;
                    }
                    row.RowError += rowMsg;
                    done = true;
                }
            }
            if (!done)
            { // all rows are in 'error'
                for (int i = 0; i < commandCount; i++)
                {
                    DataRow row = batchCommands[i]._row;
                    // its possible a DBConcurrencyException exists and all rows have records affected
                    // via not overriding GetBatchedRecordsAffected or user setting the exception
                    row.RowError += message;
                }
            }
            else
            {
                affected = UpdatedRowStatusContinue(rowUpdatedEvent, batchCommands, commandCount);
            }
            if (!ContinueUpdateOnError)
            {
                throw errors; // out of Update
            }
            return affected; // return the count of successful rows within the batch failure
        }
예제 #9
0
		protected virtual void OnRowUpdated (RowUpdatedEventArgs value)
		{
			if (Events ["RowUpdated"] != null) {
				Delegate [] rowUpdatedList = Events ["RowUpdated"].GetInvocationList ();
				foreach (Delegate rowUpdated in rowUpdatedList) {
					MethodInfo rowUpdatedMethod = rowUpdated.Method;
					rowUpdatedMethod.Invoke (value, null);
				}
			}
		}
예제 #10
0
 /// <summary>
 ///   Raises the RowUpdated event of a .NET Framework data provider.
 /// </summary>
 /// <param name="value"> A <see cref="T:System.Data.Common.RowUpdatedEventArgs" /> that contains the event data. </param>
 protected override void OnRowUpdated(RowUpdatedEventArgs value)
 {
   if (RowUpdated != null)
     RowUpdated(this, (value as CUBRIDRowUpdatedEventArgs));
 }
예제 #11
0
        /// <summary>
        /// Pre-Condition:  
        /// Post-Condition: Child records will be persisted in the database, consistant with the primary key of the parent record.
        /// Description:    This method will synchronize the primary and foreign keys.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void dbDA_RowUpdated(object sender, RowUpdatedEventArgs e)
        {
            int intID = 0;
            if (_dbConn.State == ConnectionState.Closed) _dbConn.Open();

            //OleDbCommand dbCMD = new OleDbCommand("SELECT @@IDENTITY", _dbConn);
            SQLiteCommand dbCMD = new SQLiteCommand("SELECT last_insert_rowid()", _dbConn);
            if (e.StatementType == StatementType.Insert)
            {
                intID = int.Parse(dbCMD.ExecuteScalar().ToString());
                e.Row[0] = intID;
            }
        }
예제 #12
0
		protected abstract void OnRowUpdated (RowUpdatedEventArgs value);
예제 #13
0
 protected override void OnRowUpdated(RowUpdatedEventArgs value)
 {
     TemplateRowUpdatedEventHandler handler = (TemplateRowUpdatedEventHandler)Events[EventRowUpdated];
     if ((null != handler) && (value is TemplateRowUpdatedEventArgs))
     {
         handler(this, (TemplateRowUpdatedEventArgs)value);
     }
 }
예제 #14
0
		/// <summary>
		/// Raises the RowUpdating event of Sqlite data provider.
		/// </summary>
		/// <param name="args">An RowUpdatingEventArgs that contains the event data.</param>
		protected override void OnRowUpdated (RowUpdatedEventArgs args)
		{
			if (RowUpdated != null)
				RowUpdated(this, args);
		}
예제 #15
0
        // If it's an Insert we fetch the @@Identity value and stuff it in the proper column
        protected void OnRowUpdated(object sender, RowUpdatedEventArgs e)
        {
            try
            {
                if(e.Status == UpdateStatus.Continue && e.StatementType == StatementType.Insert)
                {
                    TransactionMgr txMgr = TransactionMgr.ThreadTransactionMgr();

                    string[] identityCols = this.GetAutoKeyColumns().Split(';');

                    SQLiteCommand cmd = new SQLiteCommand();

                    foreach(string col in identityCols)
                    {
                         cmd.CommandText = "SELECT last_insert_rowid()";

                        // We make sure we enlist in the ongoing transaction, otherwise, we
                        // would most likely deadlock
                        txMgr.Enlist(cmd, this);
                        object o = cmd.ExecuteScalar(); // Get the Identity Value
                        txMgr.DeEnlist(cmd, this);

                        if(o != null)
                        {
                            e.Row[col] = o;
                        }
                    }

                    e.Row.AcceptChanges();
                }
            }
            catch {}
        }
예제 #16
0
        public void Status_SetInvalidUpdateStatus_ThrowsArgumentOutOfRangeException()
        {
            var args = new RowUpdatedEventArgs(null, null, 0, null);

            AssertExtensions.Throws <ArgumentOutOfRangeException>(nameof(UpdateStatus), () => args.Status = (UpdateStatus)100);
        }
예제 #17
0
 protected override void OnRowUpdated(System.Data.Common.RowUpdatedEventArgs value)
 {
 }
예제 #18
0
 protected virtual void OnRowUpdated(RowUpdatedEventArgs value)
 {
 }
예제 #19
0
 virtual protected void OnRowUpdated(RowUpdatedEventArgs value) { // V1.0.3300
 }
예제 #20
0
		protected override void OnRowUpdated(RowUpdatedEventArgs value) {
			if (this.RowUpdated != null) {
				this.RowUpdated(this, value as MySqlRowUpdatedEventArgs);
			}
		}
예제 #21
0
 override protected void OnRowUpdated(RowUpdatedEventArgs value) {
     SqlRowUpdatedEventHandler handler = (SqlRowUpdatedEventHandler) Events[EventRowUpdated];
     if ((null != handler) && (value is SqlRowUpdatedEventArgs)) {
         handler(this, (SqlRowUpdatedEventArgs) value);
     }
     base.OnRowUpdated(value);
 }
예제 #22
0
 protected override void OnRowUpdated(RowUpdatedEventArgs value)
 {
     var handler = Events[updatedEventKey] as EventHandler<RowUpdatedEventArgs>;
     if (handler != null)
         handler(this, value);
 }
예제 #23
0
 protected override void OnRowUpdated(RowUpdatedEventArgs value)
 {
     EventHandler<H2RowUpdatedEventArgs> handler = (EventHandler<H2RowUpdatedEventArgs>)Events[EventRowUpdated];
     if (null != handler)
     {
         handler(this, (H2RowUpdatedEventArgs)value);
     }
 }
 override protected void OnRowUpdated(RowUpdatedEventArgs value)
 {
     VirtuosoRowUpdatedEventHandler handler = (VirtuosoRowUpdatedEventHandler) Events[EventRowUpdated];
     if ((null != handler) && (value is VirtuosoRowUpdatedEventArgs)) 
     {
         handler(this, (VirtuosoRowUpdatedEventArgs) value);
     }
 }
예제 #25
0
        private void UpdateBatchExecute(BatchCommandInfo[] batchCommands, int commandCount, RowUpdatedEventArgs rowUpdatedEvent)
        {
            try
            {
                // the batch execution may succeed, partially succeed and throw an exception (or not), or totally fail
                int recordsAffected = ExecuteBatch();
                rowUpdatedEvent.AdapterInit(recordsAffected);
            }
            catch (DbException e)
            {
                // an exception was thrown be but some part of the batch may have been succesfull
                ADP.TraceExceptionForCapture(e);
                rowUpdatedEvent.Errors = e;
                rowUpdatedEvent.Status = UpdateStatus.ErrorsOccurred;
            }
            Data.MissingMappingAction missingMapping = UpdateMappingAction;
            Data.MissingSchemaAction missingSchema = UpdateSchemaAction;

            int checkRecordsAffected = 0;
            bool hasConcurrencyViolation = false;
            List<DataRow> rows = null;

            // walk through the batch to build the sum of recordsAffected
            //      determine possible indivdual messages per datarow
            //      determine possible concurrency violations per datarow
            //      map output parameters to the datarow
            for (int bc = 0; bc < commandCount; ++bc)
            {
                BatchCommandInfo batchCommand = batchCommands[bc];
                StatementType statementType = batchCommand._statementType;

                // default implementation always returns 1, derived classes must override
                // otherwise DbConcurrencyException will only be thrown if sum of all records in batch is 0
                int rowAffected;
                if (GetBatchedRecordsAffected(batchCommand._commandIdentifier, out rowAffected, out batchCommands[bc]._errors))
                {
                    batchCommands[bc]._recordsAffected = rowAffected;
                }

                if ((null == batchCommands[bc]._errors) && batchCommands[bc]._recordsAffected.HasValue)
                {
                    // determine possible concurrency violations per datarow
                    if ((StatementType.Update == statementType) || (StatementType.Delete == statementType))
                    {
                        checkRecordsAffected++;
                        if (0 == rowAffected)
                        {
                            if (null == rows)
                            {
                                rows = new List<DataRow>();
                            }
                            batchCommands[bc]._errors = ADP.UpdateConcurrencyViolation(batchCommands[bc]._statementType, 0, 1, new DataRow[] { rowUpdatedEvent.Rows[bc] });
                            hasConcurrencyViolation = true;
                            rows.Add(rowUpdatedEvent.Rows[bc]);
                        }
                    }

                    // map output parameters to the datarow
                    if (((StatementType.Insert == statementType) || (StatementType.Update == statementType))
                        && (0 != (UpdateRowSource.OutputParameters & batchCommand._updatedRowSource)) && (0 != rowAffected))
                    {
                        if (StatementType.Insert == statementType)
                        {
                            // AcceptChanges for 'added' rows so backend generated keys that are returned
                            // propagte into the datatable correctly.
                            rowUpdatedEvent.Rows[bc].AcceptChanges();
                        }

                        for (int i = 0; i < batchCommand._parameterCount; ++i)
                        {
                            IDataParameter parameter = GetBatchedParameter(batchCommand._commandIdentifier, i);
                            ParameterOutput(parameter, batchCommand._row, rowUpdatedEvent.TableMapping, missingMapping, missingSchema);
                        }
                    }
                }
            }

            if (null == rowUpdatedEvent.Errors)
            {
                // Only error if RecordsAffect == 0, not -1.  A value of -1 means no count was received from server,
                // do not error in that situation (means 'set nocount on' was executed on server).
                if (UpdateStatus.Continue == rowUpdatedEvent.Status)
                {
                    if ((0 < checkRecordsAffected) && ((0 == rowUpdatedEvent.RecordsAffected) || hasConcurrencyViolation))
                    {
                        // bug50526, an exception if no records affected and attempted an Update/Delete
                        Debug.Assert(null == rowUpdatedEvent.Errors, "Continue - but contains an exception");
                        DataRow[] rowsInError = (null != rows) ? rows.ToArray() : rowUpdatedEvent.Rows;
                        rowUpdatedEvent.Errors = ADP.UpdateConcurrencyViolation(StatementType.Batch, commandCount - rowsInError.Length, commandCount, rowsInError);
                        rowUpdatedEvent.Status = UpdateStatus.ErrorsOccurred;
                    }
                }
            }
        }
 protected override void OnRowUpdated(RowUpdatedEventArgs value)
 {
     OdbcRowUpdatedEventHandler handler = (OdbcRowUpdatedEventHandler) base.Events[EventRowUpdated];
     if ((handler != null) && (value is OdbcRowUpdatedEventArgs))
     {
         handler(this, (OdbcRowUpdatedEventArgs) value);
     }
     base.OnRowUpdated(value);
 }
예제 #27
0
        private void UpdateRowExecute(RowUpdatedEventArgs rowUpdatedEvent, IDbCommand dataCommand, StatementType cmdIndex)
        {
            Debug.Assert(null != rowUpdatedEvent, "null rowUpdatedEvent");
            Debug.Assert(null != dataCommand, "null dataCommand");
            Debug.Assert(rowUpdatedEvent.Command == dataCommand, "dataCommand differs from rowUpdatedEvent");

            bool insertAcceptChanges = true;
            UpdateRowSource updatedRowSource = dataCommand.UpdatedRowSource;
            if ((StatementType.Delete == cmdIndex) || (0 == (UpdateRowSource.FirstReturnedRecord & updatedRowSource)))
            {
                int recordsAffected = dataCommand.ExecuteNonQuery();
                rowUpdatedEvent.AdapterInit(recordsAffected);
            }
            else if ((StatementType.Insert == cmdIndex) || (StatementType.Update == cmdIndex))
            {
                // we only care about the first row of the first result
                using (IDataReader dataReader = dataCommand.ExecuteReader(CommandBehavior.SequentialAccess))
                {
                    DataReaderContainer readerHandler = DataReaderContainer.Create(dataReader, ReturnProviderSpecificTypes);
                    try
                    {
                        bool getData = false;
                        do
                        {
                            // advance to the first row returning result set
                            // determined by actually having columns in the result set
                            if (0 < readerHandler.FieldCount)
                            {
                                getData = true;
                                break;
                            }
                        } while (dataReader.NextResult());

                        if (getData && (0 != dataReader.RecordsAffected))
                        {
                            SchemaMapping mapping = new SchemaMapping(this, null, rowUpdatedEvent.Row.Table, readerHandler, false, SchemaType.Mapped, rowUpdatedEvent.TableMapping.SourceTable, true, null, null);

                            if ((null != mapping.DataTable) && (null != mapping.DataValues))
                            {
                                if (dataReader.Read())
                                {
                                    if ((StatementType.Insert == cmdIndex) && insertAcceptChanges)
                                    {
                                        rowUpdatedEvent.Row.AcceptChanges();
                                        insertAcceptChanges = false;
                                    }
                                    mapping.ApplyToDataRow(rowUpdatedEvent.Row);
                                }
                            }
                        }
                    }
                    finally
                    {
                        // using Close which can optimize its { while(dataReader.NextResult()); } loop
                        dataReader.Close();

                        // RecordsAffected is available after Close, but don't trust it after Dispose
                        int recordsAffected = dataReader.RecordsAffected;
                        rowUpdatedEvent.AdapterInit(recordsAffected);
                    }
                }
            }
            else
            {
                // StatementType.Select, StatementType.Batch
                Debug.Assert(false, "unexpected StatementType");
            }

            // map the parameter results to the dataSet
            if (((StatementType.Insert == cmdIndex) || (StatementType.Update == cmdIndex))
                && (0 != (UpdateRowSource.OutputParameters & updatedRowSource)) && (0 != rowUpdatedEvent.RecordsAffected))
            {
                if ((StatementType.Insert == cmdIndex) && insertAcceptChanges)
                {
                    rowUpdatedEvent.Row.AcceptChanges();
                }
                ParameterOutput(dataCommand.Parameters, rowUpdatedEvent.Row, rowUpdatedEvent.TableMapping);
            }

            // Only error if RecordsAffect == 0, not -1.  A value of -1 means no count was received from server,
            // do not error in that situation (means 'set nocount on' was executed on server).
            switch (rowUpdatedEvent.Status)
            {
                case UpdateStatus.Continue:
                    switch (cmdIndex)
                    {
                        case StatementType.Update:
                        case StatementType.Delete:
                            if (0 == rowUpdatedEvent.RecordsAffected)
                            {
                                Debug.Assert(null == rowUpdatedEvent.Errors, "Continue - but contains an exception");
                                rowUpdatedEvent.Errors = ADP.UpdateConcurrencyViolation(cmdIndex, rowUpdatedEvent.RecordsAffected, 1, new DataRow[] { rowUpdatedEvent.Row });
                                rowUpdatedEvent.Status = UpdateStatus.ErrorsOccurred;
                            }
                            break;
                    }
                    break;
            }
        }
예제 #28
0
		protected override void OnRowUpdated(RowUpdatedEventArgs value)
		{
			NpgsqlEventLog.LogMethodEnter(LogLevel.Debug, CLASSNAME, "OnRowUpdated");
			//base.OnRowUpdated(value);
			if ((RowUpdated != null) && (value is NpgsqlRowUpdatedEventArgs))
			{
				RowUpdated(this, (NpgsqlRowUpdatedEventArgs) value);
			}
		}
예제 #29
0
 private int UpdatedRowStatus(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, int commandCount)
 {
     Debug.Assert(null != rowUpdatedEvent, "null rowUpdatedEvent");
     int cumulativeDataRowsAffected = 0;
     switch (rowUpdatedEvent.Status)
     {
         case UpdateStatus.Continue:
             cumulativeDataRowsAffected = UpdatedRowStatusContinue(rowUpdatedEvent, batchCommands, commandCount);
             break; // return to foreach DataRow
         case UpdateStatus.ErrorsOccurred:
             cumulativeDataRowsAffected = UpdatedRowStatusErrors(rowUpdatedEvent, batchCommands, commandCount);
             break; // no datarow affected if ErrorsOccured
         case UpdateStatus.SkipCurrentRow:
         case UpdateStatus.SkipAllRemainingRows: // cancel the Update method
             cumulativeDataRowsAffected = UpdatedRowStatusSkip(batchCommands, commandCount);
             break; // foreach DataRow without accepting changes on this row (but user may haved accepted chagnes for us)
         default:
             throw ADP.InvalidUpdateStatus(rowUpdatedEvent.Status);
     } // switch RowUpdatedEventArgs.Status
     return cumulativeDataRowsAffected;
 }
		protected override void OnRowUpdated(RowUpdatedEventArgs value)
		{
			FbRowUpdatedEventHandler handler = null;

			handler = (FbRowUpdatedEventHandler)base.Events[EventRowUpdated];

			if ((handler != null) &&
				(value is FbRowUpdatedEventArgs) &&
				(value != null))
			{
				handler(this, (FbRowUpdatedEventArgs)value);
			}
		}
예제 #31
0
        private int UpdatedRowStatusContinue(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, int commandCount)
        {
            Debug.Assert(null != batchCommands, "null batchCommands?");
            int cumulativeDataRowsAffected = 0;
            // 1. We delay accepting the changes until after we fire RowUpdatedEvent
            //    so the user has a chance to call RejectChanges for any given reason
            // 2. If the DataSource return 0 records affected, its an indication that
            //    the command didn't take so we don't want to automatically
            //    AcceptChanges.
            // With 'set nocount on' the count will be -1, accept changes in that case too.
            // 3.  Don't accept changes if no rows were affected, the user needs
            //     to know that there is a concurrency violation

            // Only accept changes if the row is not already accepted, ie detached.
            bool acdu = AcceptChangesDuringUpdate;
            for (int i = 0; i < commandCount; i++)
            {
                DataRow row = batchCommands[i]._row;
                if ((null == batchCommands[i]._errors) && batchCommands[i]._recordsAffected.HasValue && (0 != batchCommands[i]._recordsAffected.Value))
                {
                    Debug.Assert(null != row, "null dataRow?");
                    if (acdu)
                    {
                        if (0 != ((DataRowState.Added | DataRowState.Deleted | DataRowState.Modified) & row.RowState))
                        {
                            row.AcceptChanges();
                        }
                    }
                    cumulativeDataRowsAffected++;
                }
            }
            return cumulativeDataRowsAffected;
        }
예제 #32
0
		protected override void OnRowUpdated (RowUpdatedEventArgs value) 
		{
			if (RowUpdated != null)
				RowUpdated (this, (SqlRowUpdatedEventArgs) value);
		}
예제 #33
0
        protected virtual int Update(DataRow [] dataRows, DataTableMapping tableMapping)
        {
            int updateCount = 0;

            foreach (DataRow row in dataRows)
            {
                StatementType statementType = StatementType.Update;
                IDbCommand    command       = null;
                string        commandName   = String.Empty;

                switch (row.RowState)
                {
                case DataRowState.Added:
                    statementType = StatementType.Insert;
                    command       = ((IDbDataAdapter)this).InsertCommand;
                    commandName   = "Insert";
                    break;

                case DataRowState.Deleted:
                    statementType = StatementType.Delete;
                    command       = ((IDbDataAdapter)this).DeleteCommand;
                    commandName   = "Delete";
                    break;

                case DataRowState.Modified:
                    statementType = StatementType.Update;
                    command       = ((IDbDataAdapter)this).UpdateCommand;
                    commandName   = "Update";
                    break;

                case DataRowState.Unchanged:
                case DataRowState.Detached:
                    continue;
                }

                RowUpdatingEventArgs argsUpdating = CreateRowUpdatingEvent(row, command, statementType, tableMapping);
                row.RowError = String.Empty;
                OnRowUpdating(argsUpdating);
                switch (argsUpdating.Status)
                {
                case UpdateStatus.Continue:
                    //continue in update operation
                    break;

                case UpdateStatus.ErrorsOccurred:
                    if (argsUpdating.Errors == null)
                    {
                        argsUpdating.Errors = ExceptionHelper.RowUpdatedError();
                    }
                    row.RowError += argsUpdating.Errors.Message;
                    if (!ContinueUpdateOnError)
                    {
                        throw argsUpdating.Errors;
                    }
                    continue;

                case UpdateStatus.SkipAllRemainingRows:
                    return(updateCount);

                case UpdateStatus.SkipCurrentRow:
                    updateCount++;
                    continue;

                default:
                    throw ExceptionHelper.InvalidUpdateStatus(argsUpdating.Status);
                }
                command = argsUpdating.Command;
                try {
                    if (command != null)
                    {
                        DataColumnMappingCollection columnMappings = tableMapping.ColumnMappings;
                        foreach (IDataParameter parameter in command.Parameters)
                        {
                            if ((parameter.Direction & ParameterDirection.Input) == 0)
                            {
                                continue;
                            }

                            DataRowVersion rowVersion = parameter.SourceVersion;
                            // Parameter version is ignored for non-update commands
                            if (statementType == StatementType.Delete)
                            {
                                rowVersion = DataRowVersion.Original;
                            }

                            string dsColumnName = parameter.SourceColumn;
                            if (columnMappings.Contains(dsColumnName))
                            {
                                dsColumnName    = columnMappings [dsColumnName].DataSetColumn;
                                parameter.Value = row [dsColumnName, rowVersion];
                            }
                            else
                            {
                                parameter.Value = null;
                            }

                            DbParameter nullCheckParam = parameter as DbParameter;

                            if (nullCheckParam != null && nullCheckParam.SourceColumnNullMapping)
                            {
                                if (parameter.Value != null && parameter.Value != DBNull.Value)
                                {
                                    nullCheckParam.Value = 0;
                                }
                                else
                                {
                                    nullCheckParam.Value = 1;
                                }
                                nullCheckParam = null;
                            }
                        }
                    }
                } catch (Exception e) {
                    argsUpdating.Errors = e;
                    argsUpdating.Status = UpdateStatus.ErrorsOccurred;
                }

                IDataReader reader = null;
                try {
                    if (command == null)
                    {
                        throw ExceptionHelper.UpdateRequiresCommand(commandName);
                    }

                    CommandBehavior commandBehavior = CommandBehavior.Default;
                    if (command.Connection.State == ConnectionState.Closed)
                    {
                        command.Connection.Open();
                        commandBehavior |= CommandBehavior.CloseConnection;
                    }

                    // use ExecuteReader because we want to use the commandbehavior parameter.
                    // so the connection will be closed if needed.
                    reader = command.ExecuteReader(commandBehavior);

                    // update the current row, if the update command returns any resultset
                    // ignore other than the first record.
                    DataColumnMappingCollection columnMappings = tableMapping.ColumnMappings;

                    if (command.UpdatedRowSource == UpdateRowSource.Both ||
                        command.UpdatedRowSource == UpdateRowSource.FirstReturnedRecord)
                    {
                        if (reader.Read())
                        {
                            DataTable retSchema = reader.GetSchemaTable();
                            foreach (DataRow dr in retSchema.Rows)
                            {
                                string columnName    = dr ["ColumnName"].ToString();
                                string dstColumnName = columnName;
                                if (columnMappings != null &&
                                    columnMappings.Contains(columnName))
                                {
                                    dstColumnName = columnMappings [dstColumnName].DataSetColumn;
                                }
                                DataColumn dstColumn = row.Table.Columns [dstColumnName];
                                if (dstColumn == null ||
                                    (dstColumn.Expression != null &&
                                     dstColumn.Expression.Length > 0))
                                {
                                    continue;
                                }
                                // info from : http://www.error-bank.com/microsoft.public.dotnet.framework.windowsforms.databinding/
                                // [email protected]_Thread.aspx
                                // disable readonly for non-expression columns.
                                bool readOnlyState = dstColumn.ReadOnly;
                                dstColumn.ReadOnly = false;
                                try {
                                    row [dstColumnName] = reader [columnName];
                                } finally {
                                    dstColumn.ReadOnly = readOnlyState;
                                }
                            }
                        }
                    }
                    reader.Close();

                    int tmp = reader.RecordsAffected;                     // records affected is valid only after closing reader
                    // if the execute does not effect any rows we throw an exception.
                    if (tmp == 0)
                    {
                        throw new DBConcurrencyException("Concurrency violation: the " +
                                                         commandName + "Command affected 0 records.", null,
                                                         new DataRow [] { row });
                    }
                    updateCount += tmp;

                    if (command.UpdatedRowSource == UpdateRowSource.Both ||
                        command.UpdatedRowSource == UpdateRowSource.OutputParameters)
                    {
                        // Update output parameters to row values
                        foreach (IDataParameter parameter in command.Parameters)
                        {
                            if (parameter.Direction != ParameterDirection.InputOutput &&
                                parameter.Direction != ParameterDirection.Output &&
                                parameter.Direction != ParameterDirection.ReturnValue)
                            {
                                continue;
                            }

                            string dsColumnName = parameter.SourceColumn;
                            if (columnMappings != null &&
                                columnMappings.Contains(parameter.SourceColumn))
                            {
                                dsColumnName = columnMappings [parameter.SourceColumn].DataSetColumn;
                            }
                            DataColumn dstColumn = row.Table.Columns [dsColumnName];
                            if (dstColumn == null ||
                                (dstColumn.Expression != null &&
                                 dstColumn.Expression.Length > 0))
                            {
                                continue;
                            }
                            bool readOnlyState = dstColumn.ReadOnly;
                            dstColumn.ReadOnly = false;
                            try {
                                row [dsColumnName] = parameter.Value;
                            } finally {
                                dstColumn.ReadOnly = readOnlyState;
                            }
                        }
                    }

                    RowUpdatedEventArgs updatedArgs = CreateRowUpdatedEvent(row, command, statementType, tableMapping);
                    OnRowUpdated(updatedArgs);
                    switch (updatedArgs.Status)
                    {
                    case UpdateStatus.Continue:
                        break;

                    case UpdateStatus.ErrorsOccurred:
                        if (updatedArgs.Errors == null)
                        {
                            updatedArgs.Errors = ExceptionHelper.RowUpdatedError();
                        }
                        row.RowError += updatedArgs.Errors.Message;
                        if (!ContinueUpdateOnError)
                        {
                            throw updatedArgs.Errors;
                        }
                        break;

                    case UpdateStatus.SkipCurrentRow:
                        continue;

                    case UpdateStatus.SkipAllRemainingRows:
                        return(updateCount);
                    }
                    if (!AcceptChangesDuringUpdate)
                    {
                        continue;
                    }
                    row.AcceptChanges();
                } catch (Exception e) {
                    row.RowError = e.Message;
                    if (!ContinueUpdateOnError)
                    {
                        throw e;
                    }
                } finally {
                    if (reader != null && !reader.IsClosed)
                    {
                        reader.Close();
                    }
                }
            }
            return(updateCount);
        }