2 // System.Data.Common.DbDataAdapter.cs
5 // Rodrigo Moya (rodrigo@ximian.com)
6 // Tim Coleman (tim@timcoleman.com)
7 // Sureshkumar T <tsureshkumar@novell.com>
10 // Copyright (C) Tim Coleman, 2002-2003
14 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 using System.Collections;
38 using System.ComponentModel;
40 using System.Reflection;
41 using System.Runtime.InteropServices;
43 namespace System.Data.Common {
45 public abstract class DbDataAdapter : DataAdapter, IDbDataAdapter, IDataAdapter, ICloneable
47 public abstract class DbDataAdapter : DataAdapter, ICloneable
52 public const string DefaultSourceTableName = "Table";
53 const string DefaultSourceColumnName = "Column";
54 CommandBehavior _behavior = CommandBehavior.Default;
57 IDbCommand _selectCommand;
58 IDbCommand _updateCommand;
59 IDbCommand _deleteCommand;
60 IDbCommand _insertCommand;
67 protected DbDataAdapter()
71 protected DbDataAdapter (DbDataAdapter adapter) : base (adapter)
80 protected internal CommandBehavior FillCommandBehavior {
81 get { return _behavior; }
82 set { _behavior = value; }
85 IDbCommand IDbDataAdapter.SelectCommand {
86 get { return _selectCommand; }
87 set { _selectCommand = value; }
90 IDbCommand IDbDataAdapter.UpdateCommand{
91 get { return _updateCommand; }
92 set { _updateCommand = value; }
95 IDbCommand IDbDataAdapter.DeleteCommand{
96 get { return _deleteCommand; }
97 set { _deleteCommand = value; }
100 IDbCommand IDbDataAdapter.InsertCommand{
101 get { return _insertCommand; }
102 set { _insertCommand = value; }
106 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
107 public DbCommand SelectCommand {
108 get { return (DbCommand) ((IDbDataAdapter) this).SelectCommand; }
109 set { ((IDbDataAdapter) this).SelectCommand = value; }
113 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
114 public DbCommand DeleteCommand {
115 get { return (DbCommand) ((IDbDataAdapter) this).DeleteCommand; }
116 set { ((IDbDataAdapter) this).DeleteCommand = value; }
120 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
121 public DbCommand InsertCommand {
122 get { return (DbCommand) ((IDbDataAdapter) this).InsertCommand; }
123 set { ((IDbDataAdapter) this).InsertCommand = value; }
127 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
128 public DbCommand UpdateCommand {
129 get { return (DbCommand) ((IDbDataAdapter) this).UpdateCommand; }
130 set { ((IDbDataAdapter) this).UpdateCommand = value; }
134 public virtual int UpdateBatchSize {
138 throw new NotSupportedException ();
142 IDbCommand SelectCommand {
143 get { return ((IDbDataAdapter) this).SelectCommand; }
146 IDbCommand UpdateCommand {
147 get { return ((IDbDataAdapter) this).UpdateCommand; }
150 IDbCommand DeleteCommand {
151 get { return ((IDbDataAdapter) this).DeleteCommand; }
154 IDbCommand InsertCommand {
155 get { return ((IDbDataAdapter) this).InsertCommand; }
159 #endregion // Properties
163 #if ONLY_1_0 || ONLY_1_1
165 [DataCategory ("Fill")]
166 [DataSysDescription ("Event triggered when a recoverable error occurs during Fill.")]
167 public event FillErrorEventHandler FillError;
175 protected virtual RowUpdatedEventArgs CreateRowUpdatedEvent (DataRow dataRow, IDbCommand command,
176 StatementType statementType,
177 DataTableMapping tableMapping)
179 return new RowUpdatedEventArgs (dataRow, command, statementType, tableMapping);
182 protected virtual RowUpdatingEventArgs CreateRowUpdatingEvent (DataRow dataRow, IDbCommand command,
183 StatementType statementType,
184 DataTableMapping tableMapping)
186 return new RowUpdatingEventArgs (dataRow, command, statementType, tableMapping);
189 protected virtual void OnRowUpdated (RowUpdatedEventArgs value)
191 if (Events ["RowUpdated"] != null) {
192 Delegate [] rowUpdatedList = Events ["RowUpdated"].GetInvocationList ();
193 foreach (Delegate rowUpdated in rowUpdatedList) {
194 MethodInfo rowUpdatedMethod = rowUpdated.Method;
195 rowUpdatedMethod.Invoke (value, null);
200 protected virtual void OnRowUpdating (RowUpdatingEventArgs value)
202 if (Events ["RowUpdating"] != null) {
203 Delegate [] rowUpdatingList = Events ["RowUpdating"].GetInvocationList ();
204 foreach (Delegate rowUpdating in rowUpdatingList) {
205 MethodInfo rowUpdatingMethod = rowUpdating.Method;
206 rowUpdatingMethod.Invoke (value, null);
211 protected abstract RowUpdatedEventArgs CreateRowUpdatedEvent (DataRow dataRow, IDbCommand command,
212 StatementType statementType,
213 DataTableMapping tableMapping);
215 protected abstract RowUpdatingEventArgs CreateRowUpdatingEvent (DataRow dataRow, IDbCommand command,
216 StatementType statementType,
217 DataTableMapping tableMapping);
219 protected abstract void OnRowUpdated (RowUpdatedEventArgs value);
220 protected abstract void OnRowUpdating (RowUpdatingEventArgs value);
223 protected override void Dispose (bool disposing)
226 IDbDataAdapter da = (IDbDataAdapter) this;
227 if (da.SelectCommand != null) {
228 da.SelectCommand.Dispose();
229 da.SelectCommand = null;
231 if (da.InsertCommand != null) {
232 da.InsertCommand.Dispose();
233 da.InsertCommand = null;
235 if (da.UpdateCommand != null) {
236 da.UpdateCommand.Dispose();
237 da.UpdateCommand = null;
239 if (da.DeleteCommand != null) {
240 da.DeleteCommand.Dispose();
241 da.DeleteCommand = null;
246 public override int Fill (DataSet dataSet)
248 return Fill (dataSet, 0, 0, DefaultSourceTableName, ((IDbDataAdapter) this).SelectCommand, _behavior);
251 public int Fill (DataTable dataTable)
253 if (dataTable == null)
254 throw new ArgumentNullException ("DataTable");
256 return Fill (dataTable, ((IDbDataAdapter) this).SelectCommand, _behavior);
259 public int Fill (DataSet dataSet, string srcTable)
261 return Fill (dataSet, 0, 0, srcTable, ((IDbDataAdapter) this).SelectCommand, _behavior);
269 virtual new int Fill (DataTable dataTable, IDataReader dataReader)
271 return base.FillInternal (dataTable, dataReader);
274 protected virtual int Fill (DataTable dataTable, IDbCommand command, CommandBehavior behavior)
276 CommandBehavior commandBehavior = behavior;
278 // first see that the connection is not close.
279 if (command.Connection.State == ConnectionState.Closed)
281 command.Connection.Open ();
282 commandBehavior |= CommandBehavior.CloseConnection;
284 return Fill (dataTable, command.ExecuteReader (commandBehavior));
287 public int Fill (DataSet dataSet, int startRecord, int maxRecords, string srcTable)
289 return this.Fill (dataSet, startRecord, maxRecords, srcTable, ((IDbDataAdapter) this).SelectCommand, _behavior);
294 public int Fill (int startRecord, int maxRecords, params DataTable[] dataTables)
296 throw new NotImplementedException ();
300 protected virtual int Fill (DataTable[] dataTables, int startRecord, int maxRecords, IDbCommand command, CommandBehavior behavior)
302 throw new NotImplementedException ();
308 protected virtual int Fill (DataSet dataSet, string srcTable, IDataReader dataReader, int startRecord, int maxRecords)
310 return base.FillInternal (dataSet, srcTable, dataReader, startRecord, maxRecords);
314 protected virtual int Fill (DataSet dataSet, int startRecord, int maxRecords, string srcTable, IDbCommand command, CommandBehavior behavior)
316 if (command.Connection == null) {
317 throw new InvalidOperationException ("Connection state is closed");
319 if (MissingSchemaAction == MissingSchemaAction.AddWithKey)
320 behavior |= CommandBehavior.KeyInfo;
321 CommandBehavior commandBehavior = behavior;
323 if (command.Connection.State == ConnectionState.Closed) {
324 command.Connection.Open ();
325 commandBehavior |= CommandBehavior.CloseConnection;
327 return Fill (dataSet, srcTable, command.ExecuteReader (commandBehavior), startRecord, maxRecords);
332 /// Fills the given datatable using values from reader. if a value
333 /// for a column is null, that will be filled with default value.
335 /// <returns>No. of rows affected </returns>
336 internal static int FillFromReader (DataTable table,
341 LoadOption loadOption
344 if (reader.FieldCount == 0)
347 for (int i = 0; i < start; i++)
351 object [] values = new object [mapping.Length];
352 while (reader.Read () &&
353 (length == 0 || counter < length)) {
355 for (int i = 0 ; i < mapping.Length; i++)
356 values [i] = mapping [i] < 0 ? null : reader [mapping [i]];
358 table.BeginLoadData ();
359 table.LoadDataRow (values, loadOption);
360 table.EndLoadData ();
366 internal static int FillFromReader (DataTable table,
371 LoadOption loadOption,
372 FillErrorEventHandler errorHandler)
374 if (reader.FieldCount == 0)
377 for (int i = 0; i < start; i++)
381 object [] values = new object [mapping.Length];
382 while (reader.Read () &&
383 (length == 0 || counter < length)) {
385 for (int i = 0 ; i < mapping.Length; i++)
386 values [i] = mapping [i] < 0 ? null : reader [mapping [i]];
388 table.BeginLoadData ();
390 table.LoadDataRow (values, loadOption);
391 } catch (Exception e) {
392 FillErrorEventArgs args = new FillErrorEventArgs (table, values);
394 args.Continue = false;
395 errorHandler (table, args);
396 // if args.Continue is not set to true or if a handler is not set, rethrow the error..
400 table.EndLoadData ();
408 public override DataTable[] FillSchema (DataSet dataSet, SchemaType schemaType)
410 return FillSchema (dataSet, schemaType, ((IDbDataAdapter) this).SelectCommand, DefaultSourceTableName, _behavior);
413 public DataTable FillSchema (DataTable dataTable, SchemaType schemaType)
415 return FillSchema (dataTable, schemaType, ((IDbDataAdapter) this).SelectCommand, _behavior);
418 public DataTable[] FillSchema (DataSet dataSet, SchemaType schemaType, string srcTable)
420 return FillSchema (dataSet, schemaType, ((IDbDataAdapter) this).SelectCommand, srcTable, _behavior);
423 protected virtual DataTable FillSchema (DataTable dataTable, SchemaType schemaType, IDbCommand command, CommandBehavior behavior)
425 if (dataTable == null)
426 throw new ArgumentNullException ("DataTable");
428 behavior |= CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo;
429 if (command.Connection.State == ConnectionState.Closed) {
430 command.Connection.Open ();
431 behavior |= CommandBehavior.CloseConnection;
434 IDataReader reader = command.ExecuteReader (behavior);
437 string tableName = SetupSchema (schemaType, dataTable.TableName);
438 if (tableName != null)
440 // FillSchema should add the KeyInfo unless MissingSchemaAction
441 // is set to Ignore or Error.
442 MissingSchemaAction schemaAction = MissingSchemaAction;
443 if (!(schemaAction == MissingSchemaAction.Ignore ||
444 schemaAction == MissingSchemaAction.Error))
445 schemaAction = MissingSchemaAction.AddWithKey;
447 BuildSchema (reader, dataTable, schemaType, schemaAction,
448 MissingMappingAction, TableMappings);
458 protected virtual DataTable[] FillSchema (DataSet dataSet, SchemaType schemaType, IDbCommand command, string srcTable, CommandBehavior behavior)
461 throw new ArgumentNullException ("DataSet");
463 behavior |= CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo;
464 if (command.Connection.State == ConnectionState.Closed) {
465 command.Connection.Open ();
466 behavior |= CommandBehavior.CloseConnection;
469 IDataReader reader = command.ExecuteReader (behavior);
470 ArrayList output = new ArrayList ();
471 string tableName = srcTable;
476 // FillSchema should add the KeyInfo unless MissingSchemaAction
477 // is set to Ignore or Error.
478 MissingSchemaAction schemaAction = MissingSchemaAction;
479 if (!(MissingSchemaAction == MissingSchemaAction.Ignore ||
480 MissingSchemaAction == MissingSchemaAction.Error))
481 schemaAction = MissingSchemaAction.AddWithKey;
484 tableName = SetupSchema (schemaType, tableName);
485 if (tableName != null)
487 if (dataSet.Tables.Contains (tableName))
488 table = dataSet.Tables [tableName];
491 // Do not create schema if MissingSchemAction is set to Ignore
492 if (this.MissingSchemaAction == MissingSchemaAction.Ignore)
494 table = dataSet.Tables.Add (tableName);
497 BuildSchema (reader, table, schemaType, schemaAction,
498 MissingMappingAction, TableMappings);
500 tableName = String.Format ("{0}{1}", srcTable, ++index);
502 }while (reader.NextResult ());
508 return (DataTable[]) output.ToArray (typeof (DataTable));
511 [EditorBrowsable (EditorBrowsableState.Advanced)]
512 public override IDataParameter[] GetFillParameters ()
514 IDataParameter[] parameters = new IDataParameter [SelectCommand.Parameters.Count];
515 SelectCommand.Parameters.CopyTo (parameters, 0);
520 [Obsolete ("use 'protected DbDataAdapter(DbDataAdapter)' ctor")]
521 object ICloneable.Clone ()
523 throw new NotImplementedException ();
526 public int Update (DataRow[] dataRows)
528 if (dataRows == null)
529 throw new ArgumentNullException("dataRows");
531 if (dataRows.Length == 0)
534 if (dataRows[0] == null)
535 throw new ArgumentException("dataRows[0].");
537 DataTable table = dataRows[0].Table;
539 throw new ArgumentException("table is null reference.");
541 // all rows must be in the same table
542 for (int i = 0; i < dataRows.Length; i++)
544 if (dataRows[i] == null)
545 throw new ArgumentException("dataRows[" + i + "].");
546 if (dataRows[i].Table != table)
547 throw new ArgumentException(
550 + "] is from a different DataTable than DataRow[0].");
553 // get table mapping for this rows
554 DataTableMapping tableMapping = TableMappings.GetByDataSetTable(table.TableName);
555 if (tableMapping == null)
557 tableMapping = DataTableMappingCollection.GetTableMappingBySchemaAction(
561 MissingMappingAction);
562 if (tableMapping != null) {
563 foreach (DataColumn col in table.Columns) {
564 if (tableMapping.ColumnMappings.IndexOf (col.ColumnName) >= 0)
566 DataColumnMapping columnMapping = DataColumnMappingCollection.GetColumnMappingBySchemaAction (tableMapping.ColumnMappings, col.ColumnName, MissingMappingAction);
567 if (columnMapping == null)
568 columnMapping = new DataColumnMapping (col.ColumnName, col.ColumnName);
569 tableMapping.ColumnMappings.Add (columnMapping);
572 ArrayList cmc = new ArrayList ();
573 foreach (DataColumn col in table.Columns)
574 cmc.Add (new DataColumnMapping (col.ColumnName, col.ColumnName));
576 new DataTableMapping (
579 cmc.ToArray (typeof (DataColumnMapping)) as DataColumnMapping []);
583 DataRow[] copy = table.NewRowArray(dataRows.Length);
584 Array.Copy(dataRows, 0, copy, 0, dataRows.Length);
585 return Update(copy, tableMapping);
588 public override int Update (DataSet dataSet)
590 return Update (dataSet, DefaultSourceTableName);
593 public int Update (DataTable dataTable)
596 int index = TableMappings.IndexOfDataSetTable (dataTable.TableName);
598 throw new ArgumentException ();
599 return Update (dataTable, TableMappings [index]);
601 DataTableMapping tableMapping = TableMappings.GetByDataSetTable (dataTable.TableName);
602 if (tableMapping == null)
604 tableMapping = DataTableMappingCollection.GetTableMappingBySchemaAction (
608 MissingMappingAction);
609 if (tableMapping != null) {
610 foreach (DataColumn col in dataTable.Columns) {
611 if (tableMapping.ColumnMappings.IndexOf (col.ColumnName) >= 0)
613 DataColumnMapping columnMapping = DataColumnMappingCollection.GetColumnMappingBySchemaAction (tableMapping.ColumnMappings, col.ColumnName, MissingMappingAction);
614 if (columnMapping == null)
615 columnMapping = new DataColumnMapping (col.ColumnName, col.ColumnName);
616 tableMapping.ColumnMappings.Add (columnMapping);
619 ArrayList cmc = new ArrayList ();
620 foreach (DataColumn col in dataTable.Columns)
621 cmc.Add (new DataColumnMapping (col.ColumnName, col.ColumnName));
623 new DataTableMapping (
626 cmc.ToArray (typeof (DataColumnMapping)) as DataColumnMapping []);
629 return Update (dataTable, tableMapping);
632 private int Update (DataTable dataTable, DataTableMapping tableMapping)
634 DataRow[] rows = dataTable.NewRowArray(dataTable.Rows.Count);
635 dataTable.Rows.CopyTo (rows, 0);
636 return Update (rows, tableMapping);
639 protected virtual int Update (DataRow[] dataRows, DataTableMapping tableMapping)
642 foreach (DataRow row in dataRows) {
643 StatementType statementType = StatementType.Update;
644 IDbCommand command = null;
645 string commandName = String.Empty;
647 switch (row.RowState) {
648 case DataRowState.Added:
649 statementType = StatementType.Insert;
650 command = ((IDbDataAdapter) this).InsertCommand;
651 commandName = "Insert";
653 case DataRowState.Deleted:
654 statementType = StatementType.Delete;
655 command = ((IDbDataAdapter) this).DeleteCommand;
656 commandName = "Delete";
658 case DataRowState.Modified:
659 statementType = StatementType.Update;
660 command = ((IDbDataAdapter) this).UpdateCommand;
661 commandName = "Update";
663 case DataRowState.Unchanged:
664 case DataRowState.Detached:
668 RowUpdatingEventArgs argsUpdating = CreateRowUpdatingEvent (row, command, statementType, tableMapping);
670 OnRowUpdating (argsUpdating);
671 switch (argsUpdating.Status) {
672 case UpdateStatus.Continue :
673 //continue in update operation
675 case UpdateStatus.ErrorsOccurred :
676 if (argsUpdating.Errors == null) {
677 argsUpdating.Errors = ExceptionHelper.RowUpdatedError();
679 row.RowError += argsUpdating.Errors.Message;
680 if (!ContinueUpdateOnError) {
681 throw argsUpdating.Errors;
684 case UpdateStatus.SkipAllRemainingRows :
686 case UpdateStatus.SkipCurrentRow :
690 throw ExceptionHelper.InvalidUpdateStatus (argsUpdating.Status);
692 command = argsUpdating.Command;
694 if (command != null) {
695 DataColumnMappingCollection columnMappings = tableMapping.ColumnMappings;
696 IDataParameter nullCheckParam = null;
697 foreach (IDataParameter parameter in command.Parameters) {
698 if ((parameter.Direction & ParameterDirection.Input) != 0) {
699 string dsColumnName = parameter.SourceColumn;
700 if (columnMappings.Contains(parameter.SourceColumn))
701 dsColumnName = columnMappings [parameter.SourceColumn].DataSetColumn;
702 if (dsColumnName == null || dsColumnName.Length <= 0) {
703 nullCheckParam = parameter;
707 DataRowVersion rowVersion = parameter.SourceVersion;
708 // Parameter version is ignored for non-update commands
709 if (statementType == StatementType.Delete)
710 rowVersion = DataRowVersion.Original;
712 parameter.Value = row [dsColumnName, rowVersion];
713 if (nullCheckParam != null && (parameter.Value != null
714 && parameter.Value != DBNull.Value)) {
715 nullCheckParam.Value = 0;
716 nullCheckParam = null;
722 catch (Exception e) {
723 argsUpdating.Errors = e;
724 argsUpdating.Status = UpdateStatus.ErrorsOccurred;
728 IDataReader reader = null;
730 if (command == null) {
731 throw ExceptionHelper.UpdateRequiresCommand (commandName);
734 CommandBehavior commandBehavior = CommandBehavior.Default;
735 if (command.Connection.State == ConnectionState.Closed) {
736 command.Connection.Open ();
737 commandBehavior |= CommandBehavior.CloseConnection;
740 // use ExecuteReader because we want to use the commandbehavior parameter.
741 // so the connection will be closed if needed.
742 reader = command.ExecuteReader (commandBehavior);
744 // update the current row, if the update command returns any resultset
745 // ignore other than the first record.
746 DataColumnMappingCollection columnMappings = tableMapping.ColumnMappings;
748 if (command.UpdatedRowSource == UpdateRowSource.Both ||
749 command.UpdatedRowSource == UpdateRowSource.FirstReturnedRecord) {
751 DataTable retSchema = reader.GetSchemaTable ();
752 foreach (DataRow dr in retSchema.Rows) {
753 string columnName = dr ["ColumnName"].ToString ();
754 string dstColumnName = columnName;
755 if (columnMappings != null &&
756 columnMappings.Contains(columnName))
757 dstColumnName = columnMappings [dstColumnName].DataSetColumn;
758 DataColumn dstColumn = row.Table.Columns [dstColumnName];
759 if (dstColumn == null
760 || (dstColumn.Expression != null
761 && dstColumn.Expression.Length > 0))
763 // info from : http://www.error-bank.com/microsoft.public.dotnet.framework.windowsforms.databinding/
764 // _35_hcsyiv0dha.2328@tk2msftngp10.phx.gbl_Thread.aspx
765 // disable readonly for non-expression columns.
766 bool readOnlyState = dstColumn.ReadOnly;
767 dstColumn.ReadOnly = false;
769 row [dstColumnName] = reader [columnName];
771 dstColumn.ReadOnly = readOnlyState;
778 int tmp = reader.RecordsAffected; // records affected is valid only after closing reader
779 // if the execute does not effect any rows we throw an exception.
781 throw new DBConcurrencyException("Concurrency violation: the " +
782 commandName +"Command affected 0 records.");
785 if (command.UpdatedRowSource == UpdateRowSource.Both ||
786 command.UpdatedRowSource == UpdateRowSource.OutputParameters) {
787 // Update output parameters to row values
788 foreach (IDataParameter parameter in command.Parameters) {
789 if (parameter.Direction != ParameterDirection.InputOutput
790 && parameter.Direction != ParameterDirection.Output
791 && parameter.Direction != ParameterDirection.ReturnValue)
794 string dsColumnName = parameter.SourceColumn;
795 if (columnMappings != null &&
796 columnMappings.Contains(parameter.SourceColumn))
797 dsColumnName = columnMappings [parameter.SourceColumn].DataSetColumn;
798 DataColumn dstColumn = row.Table.Columns [dsColumnName];
799 if (dstColumn == null
800 || (dstColumn.Expression != null
801 && dstColumn.Expression.Length > 0))
803 bool readOnlyState = dstColumn.ReadOnly;
804 dstColumn.ReadOnly = false;
806 row [dsColumnName] = parameter.Value;
808 dstColumn.ReadOnly = readOnlyState;
814 RowUpdatedEventArgs updatedArgs = CreateRowUpdatedEvent (row, command, statementType, tableMapping);
815 OnRowUpdated (updatedArgs);
816 switch (updatedArgs.Status) {
817 case UpdateStatus.Continue:
819 case UpdateStatus.ErrorsOccurred:
820 if (updatedArgs.Errors == null) {
821 updatedArgs.Errors = ExceptionHelper.RowUpdatedError();
823 row.RowError += updatedArgs.Errors.Message;
824 if (!ContinueUpdateOnError) {
825 throw updatedArgs.Errors;
828 case UpdateStatus.SkipCurrentRow:
830 case UpdateStatus.SkipAllRemainingRows:
834 if (!AcceptChangesDuringUpdate)
837 row.AcceptChanges ();
838 } catch(Exception e) {
839 row.RowError = e.Message;
840 if (!ContinueUpdateOnError) {
844 if (reader != null && ! reader.IsClosed) {
852 public int Update (DataSet dataSet, string sourceTable)
854 MissingMappingAction mappingAction = MissingMappingAction;
856 if (mappingAction == MissingMappingAction.Ignore)
857 mappingAction = MissingMappingAction.Error;
859 DataTableMapping tableMapping = DataTableMappingCollection.GetTableMappingBySchemaAction (TableMappings, sourceTable, sourceTable, mappingAction);
861 DataTable dataTable = dataSet.Tables[tableMapping.DataSetTable];
862 if (dataTable == null)
863 throw new ArgumentException (String.Format ("Missing table {0}",
865 return Update (dataTable, tableMapping);
869 // All the batch methods, should be implemented, if supported,
870 // by individual providers
872 protected virtual int AddToBatch (IDbCommand cmd)
874 throw new NotSupportedException ();
877 protected virtual void ClearBatch ()
879 throw new NotSupportedException ();
882 protected virtual int ExecuteBatch ()
884 throw new NotSupportedException ();
887 protected virtual IDataParameter GetBatchedParameter (int commandIdentifier, int parameterIdentifer)
889 throw new NotSupportedException ();
892 protected virtual void InitializeBatching ()
894 throw new NotSupportedException ();
897 protected virtual void TerminateBatching ()
899 throw new NotSupportedException ();
903 #if ONLY_1_0 || ONLY_1_1
904 internal override void OnFillErrorInternal (FillErrorEventArgs value)
909 protected virtual void OnFillError (FillErrorEventArgs value)
911 if (FillError != null)
912 FillError (this, value);
916 #endregion // Methods