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; } }
private void UpdateRowExecute(RowUpdatedEventArgs rowUpdatedEvent, IDbCommand dataCommand, StatementType cmdIndex) { bool flag = true; UpdateRowSource updatedRowSource = dataCommand.UpdatedRowSource; if ((StatementType.Delete == cmdIndex) || ((UpdateRowSource.FirstReturnedRecord & updatedRowSource) == UpdateRowSource.None)) { int recordsAffected = dataCommand.ExecuteNonQuery(); rowUpdatedEvent.AdapterInit(recordsAffected); } else if ((StatementType.Insert == cmdIndex) || (StatementType.Update == cmdIndex)) { using (IDataReader reader = dataCommand.ExecuteReader(CommandBehavior.SequentialAccess)) { DataReaderContainer dataReader = DataReaderContainer.Create(reader, this.ReturnProviderSpecificTypes); try { bool flag2 = false; do { if (0 < dataReader.FieldCount) { flag2 = true; break; } } while (reader.NextResult()); if (flag2 && (reader.RecordsAffected != 0)) { SchemaMapping mapping = new SchemaMapping(this, null, rowUpdatedEvent.Row.Table, dataReader, false, SchemaType.Mapped, rowUpdatedEvent.TableMapping.SourceTable, true, null, null); if (((mapping.DataTable != null) && (mapping.DataValues != null)) && reader.Read()) { if ((StatementType.Insert == cmdIndex) && flag) { rowUpdatedEvent.Row.AcceptChanges(); flag = false; } mapping.ApplyToDataRow(rowUpdatedEvent.Row); } } } finally { reader.Close(); int num = reader.RecordsAffected; rowUpdatedEvent.AdapterInit(num); } } } if (((StatementType.Insert == cmdIndex) || (StatementType.Update == cmdIndex)) && (((UpdateRowSource.OutputParameters & updatedRowSource) != UpdateRowSource.None) && (rowUpdatedEvent.RecordsAffected != 0))) { if ((StatementType.Insert == cmdIndex) && flag) { rowUpdatedEvent.Row.AcceptChanges(); } this.ParameterOutput(dataCommand.Parameters, rowUpdatedEvent.Row, rowUpdatedEvent.TableMapping); } if (rowUpdatedEvent.Status == UpdateStatus.Continue) { switch (cmdIndex) { case StatementType.Update: case StatementType.Delete: if (rowUpdatedEvent.RecordsAffected == 0) { rowUpdatedEvent.Errors = ADP.UpdateConcurrencyViolation(cmdIndex, rowUpdatedEvent.RecordsAffected, 1, new DataRow[] { rowUpdatedEvent.Row }); rowUpdatedEvent.Status = UpdateStatus.ErrorsOccurred; } return; } } }