protected override void OnRowUpdated (RowUpdatedEventArgs value) { throw new NotImplementedException (); }
/// <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); }
/// <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); }
protected override void OnRowUpdated(RowUpdatedEventArgs value) { CrmDataAdapterRowUpdatedEventHandler handler = (CrmDataAdapterRowUpdatedEventHandler)Events[EventRowUpdated]; if ((null != handler) && (value is CrmDataAdapterRowUpdatedEventArgs)) { handler(this, (CrmDataAdapterRowUpdatedEventArgs)value); } }
protected override void OnRowUpdated( RowUpdatedEventArgs value) { }
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 }
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); } } }
/// <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)); }
/// <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; } }
protected abstract void OnRowUpdated (RowUpdatedEventArgs value);
protected override void OnRowUpdated(RowUpdatedEventArgs value) { TemplateRowUpdatedEventHandler handler = (TemplateRowUpdatedEventHandler)Events[EventRowUpdated]; if ((null != handler) && (value is TemplateRowUpdatedEventArgs)) { handler(this, (TemplateRowUpdatedEventArgs)value); } }
/// <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); }
// 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 {} }
public void Status_SetInvalidUpdateStatus_ThrowsArgumentOutOfRangeException() { var args = new RowUpdatedEventArgs(null, null, 0, null); AssertExtensions.Throws <ArgumentOutOfRangeException>(nameof(UpdateStatus), () => args.Status = (UpdateStatus)100); }
protected override void OnRowUpdated(System.Data.Common.RowUpdatedEventArgs value) { }
protected virtual void OnRowUpdated(RowUpdatedEventArgs value) { }
virtual protected void OnRowUpdated(RowUpdatedEventArgs value) { // V1.0.3300 }
protected override void OnRowUpdated(RowUpdatedEventArgs value) { if (this.RowUpdated != null) { this.RowUpdated(this, value as MySqlRowUpdatedEventArgs); } }
override protected void OnRowUpdated(RowUpdatedEventArgs value) { SqlRowUpdatedEventHandler handler = (SqlRowUpdatedEventHandler) Events[EventRowUpdated]; if ((null != handler) && (value is SqlRowUpdatedEventArgs)) { handler(this, (SqlRowUpdatedEventArgs) value); } base.OnRowUpdated(value); }
protected override void OnRowUpdated(RowUpdatedEventArgs value) { var handler = Events[updatedEventKey] as EventHandler<RowUpdatedEventArgs>; if (handler != null) handler(this, value); }
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); } }
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); }
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; } }
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); } }
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); } }
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; }
protected override void OnRowUpdated (RowUpdatedEventArgs value) { if (RowUpdated != null) RowUpdated (this, (SqlRowUpdatedEventArgs) value); }
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); }