2 // System.Data.Common.DbDataAdapter.cs
5 // Rodrigo Moya (rodrigo@ximian.com)
6 // Tim Coleman (tim@timcoleman.com)
7 // Sureshkumar T <tsureshkumar@novell.com>
8 // Veerapuram Varadhan <vvaradhan@novell.com>
11 // Copyright (C) Tim Coleman, 2002-2003
15 // Copyright (C) 2004, 2009 Novell, Inc (http://www.novell.com)
17 // Permission is hereby granted, free of charge, to any person obtaining
18 // a copy of this software and associated documentation files (the
19 // "Software"), to deal in the Software without restriction, including
20 // without limitation the rights to use, copy, modify, merge, publish,
21 // distribute, sublicense, and/or sell copies of the Software, and to
22 // permit persons to whom the Software is furnished to do so, subject to
23 // the following conditions:
25 // The above copyright notice and this permission notice shall be
26 // included in all copies or substantial portions of the Software.
28 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 using System.Collections;
39 using System.ComponentModel;
41 using System.Reflection;
42 using System.Runtime.InteropServices;
44 namespace System.Data.Common
46 public abstract class DbDataAdapter : DataAdapter, IDbDataAdapter, IDataAdapter, ICloneable
50 public const string DefaultSourceTableName = "Table";
51 const string DefaultSourceColumnName = "Column";
52 CommandBehavior _behavior = CommandBehavior.Default;
54 IDbCommand _selectCommand;
55 IDbCommand _updateCommand;
56 IDbCommand _deleteCommand;
57 IDbCommand _insertCommand;
63 protected DbDataAdapter ()
67 protected DbDataAdapter (DbDataAdapter adapter) : base (adapter)
75 protected internal CommandBehavior FillCommandBehavior {
76 get { return _behavior; }
77 set { _behavior = value; }
80 IDbCommand IDbDataAdapter.SelectCommand {
81 get { return ((DbDataAdapter)this).SelectCommand; }
82 set { ((DbDataAdapter)this).SelectCommand = (DbCommand)value; }
85 IDbCommand IDbDataAdapter.UpdateCommand{
86 get { return ((DbDataAdapter)this).UpdateCommand; }
87 set { ((DbDataAdapter)this).UpdateCommand = (DbCommand)value; }
90 IDbCommand IDbDataAdapter.DeleteCommand{
91 get { return ((DbDataAdapter)this).DeleteCommand; }
92 set { ((DbDataAdapter)this).DeleteCommand = (DbCommand)value; }
95 IDbCommand IDbDataAdapter.InsertCommand{
96 get { return ((DbDataAdapter)this).InsertCommand; }
97 set { ((DbDataAdapter)this).InsertCommand = (DbCommand)value; }
101 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
102 public DbCommand SelectCommand {
104 return (DbCommand) _selectCommand;
105 //return (DbCommand) ((IDbDataAdapter)this).SelectCommand;
108 if (_selectCommand != value) {
109 _selectCommand = value;
110 ((IDbDataAdapter)this).SelectCommand = value;
116 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
117 public DbCommand DeleteCommand {
119 return (DbCommand) _deleteCommand;
120 //return (DbCommand) ((IDbDataAdapter)this).DeleteCommand;
123 if (_deleteCommand != value) {
124 _deleteCommand = value;
125 ((IDbDataAdapter)this).DeleteCommand = value;
131 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
132 public DbCommand InsertCommand {
134 return (DbCommand) _insertCommand;
135 //return (DbCommand) ((IDbDataAdapter)this).InsertCommand;
138 if (_insertCommand != value) {
139 _insertCommand = value;
140 ((IDbDataAdapter)this).InsertCommand = value;
146 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
147 public DbCommand UpdateCommand {
149 return (DbCommand) _updateCommand;
150 //return (DbCommand) ((IDbDataAdapter)this).DeleteCommand;
153 if (_updateCommand != value) {
154 _updateCommand = value;
155 ((IDbDataAdapter)this).UpdateCommand = value;
161 public virtual int UpdateBatchSize {
165 throw new NotSupportedException ();
169 #endregion // Properties
173 #if ONLY_1_0 || ONLY_1_1
174 [DataCategory ("Fill")]
175 [DataSysDescription ("Event triggered when a recoverable error occurs during Fill.")]
176 public event FillErrorEventHandler FillError;
183 protected virtual RowUpdatedEventArgs CreateRowUpdatedEvent (DataRow dataRow, IDbCommand command,
184 StatementType statementType,
185 DataTableMapping tableMapping)
187 return new RowUpdatedEventArgs (dataRow, command, statementType, tableMapping);
190 protected virtual RowUpdatingEventArgs CreateRowUpdatingEvent (DataRow dataRow, IDbCommand command,
191 StatementType statementType,
192 DataTableMapping tableMapping)
194 return new RowUpdatingEventArgs (dataRow, command, statementType, tableMapping);
197 protected virtual void OnRowUpdated (RowUpdatedEventArgs value)
199 if (Events ["RowUpdated"] != null) {
200 Delegate [] rowUpdatedList = Events ["RowUpdated"].GetInvocationList ();
201 foreach (Delegate rowUpdated in rowUpdatedList) {
202 MethodInfo rowUpdatedMethod = rowUpdated.Method;
203 rowUpdatedMethod.Invoke (value, null);
208 protected virtual void OnRowUpdating (RowUpdatingEventArgs value)
210 if (Events ["RowUpdating"] != null) {
211 Delegate [] rowUpdatingList = Events ["RowUpdating"].GetInvocationList ();
212 foreach (Delegate rowUpdating in rowUpdatingList) {
213 MethodInfo rowUpdatingMethod = rowUpdating.Method;
214 rowUpdatingMethod.Invoke (value, null);
219 protected override void Dispose (bool disposing)
222 IDbDataAdapter da = (IDbDataAdapter) this;
223 if (da.SelectCommand != null) {
224 da.SelectCommand.Dispose();
225 da.SelectCommand = null;
227 if (da.InsertCommand != null) {
228 da.InsertCommand.Dispose();
229 da.InsertCommand = null;
231 if (da.UpdateCommand != null) {
232 da.UpdateCommand.Dispose();
233 da.UpdateCommand = null;
235 if (da.DeleteCommand != null) {
236 da.DeleteCommand.Dispose();
237 da.DeleteCommand = null;
242 public override int Fill (DataSet dataSet)
244 return Fill (dataSet, 0, 0, DefaultSourceTableName, ((IDbDataAdapter) this).SelectCommand, _behavior);
247 public int Fill (DataTable dataTable)
249 if (dataTable == null)
250 throw new ArgumentNullException ("DataTable");
252 return Fill (dataTable, ((IDbDataAdapter) this).SelectCommand, _behavior);
255 public int Fill (DataSet dataSet, string srcTable)
257 return Fill (dataSet, 0, 0, srcTable, ((IDbDataAdapter) this).SelectCommand, _behavior);
261 protected virtual int Fill (DataTable dataTable, IDbCommand command, CommandBehavior behavior)
263 CommandBehavior commandBehavior = behavior;
265 // first see that the connection is not close.
266 if (command.Connection.State == ConnectionState.Closed) {
267 command.Connection.Open ();
268 commandBehavior |= CommandBehavior.CloseConnection;
270 return Fill (dataTable, command.ExecuteReader (commandBehavior));
273 public int Fill (DataSet dataSet, int startRecord, int maxRecords, string srcTable)
275 return this.Fill (dataSet, startRecord, maxRecords, srcTable, ((IDbDataAdapter) this).SelectCommand, _behavior);
279 public int Fill (int startRecord, int maxRecords, params DataTable[] dataTables)
281 throw new NotImplementedException ();
285 protected virtual int Fill (DataTable[] dataTables, int startRecord, int maxRecords, IDbCommand command, CommandBehavior behavior)
287 throw new NotImplementedException ();
290 protected virtual int Fill (DataSet dataSet, int startRecord, int maxRecords, string srcTable, IDbCommand command, CommandBehavior behavior)
292 if (command.Connection == null)
293 throw new InvalidOperationException ("Connection state is closed");
295 if (MissingSchemaAction == MissingSchemaAction.AddWithKey)
296 behavior |= CommandBehavior.KeyInfo;
297 CommandBehavior commandBehavior = behavior;
299 if (command.Connection.State == ConnectionState.Closed) {
300 command.Connection.Open ();
301 commandBehavior |= CommandBehavior.CloseConnection;
303 return Fill (dataSet, srcTable, command.ExecuteReader (commandBehavior),
304 startRecord, maxRecords);
308 /// Fills the given datatable using values from reader. if a value
309 /// for a column is null, that will be filled with default value.
311 /// <returns>No. of rows affected </returns>
312 internal static int FillFromReader (DataTable table,
317 LoadOption loadOption
320 if (reader.FieldCount == 0)
323 for (int i = 0; i < start; i++)
327 object [] values = new object [mapping.Length];
328 while (reader.Read () && (length == 0 || counter < length)) {
329 for (int i = 0 ; i < mapping.Length; i++)
330 values [i] = mapping [i] < 0 ? null : reader [mapping [i]];
331 table.BeginLoadData ();
332 table.LoadDataRow (values, loadOption);
333 table.EndLoadData ();
339 internal static int FillFromReader (DataTable table,
344 LoadOption loadOption,
345 FillErrorEventHandler errorHandler)
347 if (reader.FieldCount == 0)
350 for (int i = 0; i < start; i++)
354 object [] values = new object [mapping.Length];
355 while (reader.Read () && (length == 0 || counter < length)) {
356 for (int i = 0 ; i < mapping.Length; i++)
357 values [i] = mapping [i] < 0 ? null : reader [mapping [i]];
358 table.BeginLoadData ();
360 table.LoadDataRow (values, loadOption);
361 } catch (Exception e) {
362 FillErrorEventArgs args = new FillErrorEventArgs (table, values);
364 args.Continue = false;
365 errorHandler (table, args);
366 // if args.Continue is not set to true or if a handler is not set, rethrow the error..
370 table.EndLoadData ();
376 public override DataTable [] FillSchema (DataSet dataSet, SchemaType schemaType)
378 return FillSchema (dataSet, schemaType, ((IDbDataAdapter) this).SelectCommand, DefaultSourceTableName, _behavior);
381 public DataTable FillSchema (DataTable dataTable, SchemaType schemaType)
383 return FillSchema (dataTable, schemaType, ((IDbDataAdapter) this).SelectCommand, _behavior);
386 public DataTable [] FillSchema (DataSet dataSet, SchemaType schemaType, string srcTable)
388 return FillSchema (dataSet, schemaType, ((IDbDataAdapter) this).SelectCommand, srcTable, _behavior);
391 protected virtual DataTable FillSchema (DataTable dataTable, SchemaType schemaType, IDbCommand command, CommandBehavior behavior)
393 if (dataTable == null)
394 throw new ArgumentNullException ("DataTable");
396 behavior |= CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo;
397 if (command.Connection.State == ConnectionState.Closed) {
398 command.Connection.Open ();
399 behavior |= CommandBehavior.CloseConnection;
402 IDataReader reader = command.ExecuteReader (behavior);
404 string tableName = SetupSchema (schemaType, dataTable.TableName);
405 if (tableName != null) {
406 // FillSchema should add the KeyInfo unless MissingSchemaAction
407 // is set to Ignore or Error.
408 MissingSchemaAction schemaAction = MissingSchemaAction;
409 if (!(schemaAction == MissingSchemaAction.Ignore ||
410 schemaAction == MissingSchemaAction.Error))
411 schemaAction = MissingSchemaAction.AddWithKey;
413 BuildSchema (reader, dataTable, schemaType, schemaAction,
414 MissingMappingAction, TableMappings);
422 protected virtual DataTable[] FillSchema (DataSet dataSet, SchemaType schemaType, IDbCommand command, string srcTable, CommandBehavior behavior)
425 throw new ArgumentNullException ("DataSet");
427 behavior |= CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo;
428 if (command.Connection.State == ConnectionState.Closed) {
429 command.Connection.Open ();
430 behavior |= CommandBehavior.CloseConnection;
433 IDataReader reader = command.ExecuteReader (behavior);
434 ArrayList output = new ArrayList ();
435 string tableName = srcTable;
439 // FillSchema should add the KeyInfo unless MissingSchemaAction
440 // is set to Ignore or Error.
441 MissingSchemaAction schemaAction = MissingSchemaAction;
442 if (!(MissingSchemaAction == MissingSchemaAction.Ignore ||
443 MissingSchemaAction == MissingSchemaAction.Error))
444 schemaAction = MissingSchemaAction.AddWithKey;
447 tableName = SetupSchema (schemaType, tableName);
448 if (tableName != null) {
449 if (dataSet.Tables.Contains (tableName))
450 table = dataSet.Tables [tableName];
452 // Do not create schema if MissingSchemAction is set to Ignore
453 if (this.MissingSchemaAction == MissingSchemaAction.Ignore)
455 table = dataSet.Tables.Add (tableName);
458 BuildSchema (reader, table, schemaType, schemaAction,
459 MissingMappingAction, TableMappings);
461 tableName = String.Format ("{0}{1}", srcTable, ++index);
463 }while (reader.NextResult ());
467 return (DataTable []) output.ToArray (typeof (DataTable));
470 [EditorBrowsable (EditorBrowsableState.Advanced)]
471 public override IDataParameter[] GetFillParameters ()
473 IDbCommand selectCmd = ((IDbDataAdapter) this).SelectCommand;
474 IDataParameter[] parameters = new IDataParameter [selectCmd.Parameters.Count];
475 selectCmd.Parameters.CopyTo (parameters, 0);
480 [Obsolete ("use 'protected DbDataAdapter(DbDataAdapter)' ctor")]
481 object ICloneable.Clone ()
483 throw new NotImplementedException ();
486 public int Update (DataRow [] dataRows)
488 if (dataRows == null)
489 throw new ArgumentNullException("dataRows");
491 if (dataRows.Length == 0)
494 if (dataRows [0] == null)
495 throw new ArgumentException("dataRows[0].");
497 DataTable table = dataRows [0].Table;
499 throw new ArgumentException("table is null reference.");
501 // all rows must be in the same table
502 for (int i = 0; i < dataRows.Length; i++) {
503 if (dataRows [i] == null)
504 throw new ArgumentException ("dataRows[" + i + "].");
505 if (dataRows [i].Table != table)
506 throw new ArgumentException(
509 + "] is from a different DataTable than DataRow[0].");
512 // get table mapping for this rows
513 DataTableMapping tableMapping = TableMappings.GetByDataSetTable(table.TableName);
514 if (tableMapping == null) {
515 tableMapping = DataTableMappingCollection.GetTableMappingBySchemaAction(
519 MissingMappingAction);
520 if (tableMapping != null) {
521 foreach (DataColumn col in table.Columns) {
522 if (tableMapping.ColumnMappings.IndexOf (col.ColumnName) >= 0)
524 DataColumnMapping columnMapping = DataColumnMappingCollection.GetColumnMappingBySchemaAction (tableMapping.ColumnMappings, col.ColumnName, MissingMappingAction);
525 if (columnMapping == null)
526 columnMapping = new DataColumnMapping (col.ColumnName, col.ColumnName);
527 tableMapping.ColumnMappings.Add (columnMapping);
530 ArrayList cmc = new ArrayList ();
531 foreach (DataColumn col in table.Columns)
532 cmc.Add (new DataColumnMapping (col.ColumnName, col.ColumnName));
534 new DataTableMapping (
537 cmc.ToArray (typeof (DataColumnMapping)) as DataColumnMapping []);
541 DataRow[] copy = table.NewRowArray (dataRows.Length);
542 Array.Copy (dataRows, 0, copy, 0, dataRows.Length);
543 return Update (copy, tableMapping);
546 public override int Update (DataSet dataSet)
548 return Update (dataSet, DefaultSourceTableName);
551 public int Update (DataTable dataTable)
554 int index = TableMappings.IndexOfDataSetTable (dataTable.TableName);
556 throw new ArgumentException ();
557 return Update (dataTable, TableMappings [index]);
559 DataTableMapping tableMapping = TableMappings.GetByDataSetTable (dataTable.TableName);
560 if (tableMapping == null) {
561 tableMapping = DataTableMappingCollection.GetTableMappingBySchemaAction (
565 MissingMappingAction);
566 if (tableMapping != null) {
567 foreach (DataColumn col in dataTable.Columns) {
568 if (tableMapping.ColumnMappings.IndexOf (col.ColumnName) >= 0)
570 DataColumnMapping columnMapping = DataColumnMappingCollection.GetColumnMappingBySchemaAction (tableMapping.ColumnMappings, col.ColumnName, MissingMappingAction);
571 if (columnMapping == null)
572 columnMapping = new DataColumnMapping (col.ColumnName, col.ColumnName);
573 tableMapping.ColumnMappings.Add (columnMapping);
576 ArrayList cmc = new ArrayList ();
577 foreach (DataColumn col in dataTable.Columns)
578 cmc.Add (new DataColumnMapping (col.ColumnName, col.ColumnName));
580 new DataTableMapping (
583 cmc.ToArray (typeof (DataColumnMapping)) as DataColumnMapping []);
586 return Update (dataTable, tableMapping);
589 private int Update (DataTable dataTable, DataTableMapping tableMapping)
591 DataRow [] rows = dataTable.NewRowArray(dataTable.Rows.Count);
592 dataTable.Rows.CopyTo (rows, 0);
593 return Update (rows, tableMapping);
596 protected virtual int Update (DataRow [] dataRows, DataTableMapping tableMapping)
599 foreach (DataRow row in dataRows) {
600 StatementType statementType = StatementType.Update;
601 IDbCommand command = null;
602 string commandName = String.Empty;
604 switch (row.RowState) {
605 case DataRowState.Added:
606 statementType = StatementType.Insert;
607 command = ((IDbDataAdapter) this).InsertCommand;
608 commandName = "Insert";
610 case DataRowState.Deleted:
611 statementType = StatementType.Delete;
612 command = ((IDbDataAdapter) this).DeleteCommand;
613 commandName = "Delete";
615 case DataRowState.Modified:
616 statementType = StatementType.Update;
617 command = ((IDbDataAdapter) this).UpdateCommand;
618 commandName = "Update";
620 case DataRowState.Unchanged:
621 case DataRowState.Detached:
625 RowUpdatingEventArgs argsUpdating = CreateRowUpdatingEvent (row, command, statementType, tableMapping);
626 row.RowError = String.Empty;
627 OnRowUpdating (argsUpdating);
628 switch (argsUpdating.Status) {
629 case UpdateStatus.Continue :
630 //continue in update operation
632 case UpdateStatus.ErrorsOccurred :
633 if (argsUpdating.Errors == null)
634 argsUpdating.Errors = ExceptionHelper.RowUpdatedError();
635 row.RowError += argsUpdating.Errors.Message;
636 if (!ContinueUpdateOnError)
637 throw argsUpdating.Errors;
639 case UpdateStatus.SkipAllRemainingRows :
641 case UpdateStatus.SkipCurrentRow :
645 throw ExceptionHelper.InvalidUpdateStatus (argsUpdating.Status);
647 command = argsUpdating.Command;
649 if (command != null) {
650 DataColumnMappingCollection columnMappings = tableMapping.ColumnMappings;
652 IDataParameter nullCheckParam = null;
654 foreach (IDataParameter parameter in command.Parameters) {
655 if ((parameter.Direction & ParameterDirection.Input) == 0)
658 DataRowVersion rowVersion = parameter.SourceVersion;
659 // Parameter version is ignored for non-update commands
660 if (statementType == StatementType.Delete)
661 rowVersion = DataRowVersion.Original;
663 string dsColumnName = parameter.SourceColumn;
664 if (columnMappings.Contains(dsColumnName)) {
665 dsColumnName = columnMappings [dsColumnName].DataSetColumn;
666 parameter.Value = row [dsColumnName, rowVersion];
668 parameter.Value = null;
671 DbParameter nullCheckParam = parameter as DbParameter;
673 if (nullCheckParam != null && nullCheckParam.SourceColumnNullMapping) {
674 if (parameter.Value != null && parameter.Value != DBNull.Value)
675 nullCheckParam.Value = 0;
677 nullCheckParam.Value = 1;
678 nullCheckParam = null;
682 } catch (Exception e) {
683 argsUpdating.Errors = e;
684 argsUpdating.Status = UpdateStatus.ErrorsOccurred;
687 IDataReader reader = null;
690 throw ExceptionHelper.UpdateRequiresCommand (commandName);
692 CommandBehavior commandBehavior = CommandBehavior.Default;
693 if (command.Connection.State == ConnectionState.Closed) {
694 command.Connection.Open ();
695 commandBehavior |= CommandBehavior.CloseConnection;
698 // use ExecuteReader because we want to use the commandbehavior parameter.
699 // so the connection will be closed if needed.
700 reader = command.ExecuteReader (commandBehavior);
702 // update the current row, if the update command returns any resultset
703 // ignore other than the first record.
704 DataColumnMappingCollection columnMappings = tableMapping.ColumnMappings;
706 if (command.UpdatedRowSource == UpdateRowSource.Both ||
707 command.UpdatedRowSource == UpdateRowSource.FirstReturnedRecord) {
709 DataTable retSchema = reader.GetSchemaTable ();
710 foreach (DataRow dr in retSchema.Rows) {
711 string columnName = dr ["ColumnName"].ToString ();
712 string dstColumnName = columnName;
713 if (columnMappings != null &&
714 columnMappings.Contains(columnName))
715 dstColumnName = columnMappings [dstColumnName].DataSetColumn;
716 DataColumn dstColumn = row.Table.Columns [dstColumnName];
717 if (dstColumn == null
718 || (dstColumn.Expression != null
719 && dstColumn.Expression.Length > 0))
721 // info from : http://www.error-bank.com/microsoft.public.dotnet.framework.windowsforms.databinding/
722 // _35_hcsyiv0dha.2328@tk2msftngp10.phx.gbl_Thread.aspx
723 // disable readonly for non-expression columns.
724 bool readOnlyState = dstColumn.ReadOnly;
725 dstColumn.ReadOnly = false;
727 row [dstColumnName] = reader [columnName];
729 dstColumn.ReadOnly = readOnlyState;
736 int tmp = reader.RecordsAffected; // records affected is valid only after closing reader
737 // if the execute does not effect any rows we throw an exception.
739 throw new DBConcurrencyException("Concurrency violation: the " +
740 commandName +"Command affected 0 records.", null,
741 new DataRow [] { row });
744 if (command.UpdatedRowSource == UpdateRowSource.Both ||
745 command.UpdatedRowSource == UpdateRowSource.OutputParameters) {
746 // Update output parameters to row values
747 foreach (IDataParameter parameter in command.Parameters) {
748 if (parameter.Direction != ParameterDirection.InputOutput
749 && parameter.Direction != ParameterDirection.Output
750 && parameter.Direction != ParameterDirection.ReturnValue)
753 string dsColumnName = parameter.SourceColumn;
754 if (columnMappings != null &&
755 columnMappings.Contains(parameter.SourceColumn))
756 dsColumnName = columnMappings [parameter.SourceColumn].DataSetColumn;
757 DataColumn dstColumn = row.Table.Columns [dsColumnName];
758 if (dstColumn == null
759 || (dstColumn.Expression != null
760 && dstColumn.Expression.Length > 0))
762 bool readOnlyState = dstColumn.ReadOnly;
763 dstColumn.ReadOnly = false;
765 row [dsColumnName] = parameter.Value;
767 dstColumn.ReadOnly = readOnlyState;
772 RowUpdatedEventArgs updatedArgs = CreateRowUpdatedEvent (row, command, statementType, tableMapping);
773 OnRowUpdated (updatedArgs);
774 switch (updatedArgs.Status) {
775 case UpdateStatus.Continue:
777 case UpdateStatus.ErrorsOccurred:
778 if (updatedArgs.Errors == null)
779 updatedArgs.Errors = ExceptionHelper.RowUpdatedError();
780 row.RowError += updatedArgs.Errors.Message;
781 if (!ContinueUpdateOnError)
782 throw updatedArgs.Errors;
784 case UpdateStatus.SkipCurrentRow:
786 case UpdateStatus.SkipAllRemainingRows:
789 if (!AcceptChangesDuringUpdate)
791 row.AcceptChanges ();
792 } catch (Exception e) {
793 row.RowError = e.Message;
794 if (!ContinueUpdateOnError)
797 if (reader != null && ! reader.IsClosed)
804 public int Update (DataSet dataSet, string srcTable)
806 MissingMappingAction mappingAction = MissingMappingAction;
808 if (mappingAction == MissingMappingAction.Ignore)
809 mappingAction = MissingMappingAction.Error;
811 DataTableMapping tableMapping = DataTableMappingCollection.GetTableMappingBySchemaAction (TableMappings, srcTable, srcTable, mappingAction);
813 DataTable dataTable = dataSet.Tables [tableMapping.DataSetTable];
814 if (dataTable == null)
815 throw new ArgumentException (String.Format ("Missing table {0}",
818 /** Copied from another Update function **/
819 if (tableMapping != null) {
820 foreach (DataColumn col in dataTable.Columns) {
821 if (tableMapping.ColumnMappings.IndexOf (col.ColumnName) >= 0)
823 DataColumnMapping columnMapping = DataColumnMappingCollection.GetColumnMappingBySchemaAction (tableMapping.ColumnMappings, col.ColumnName, MissingMappingAction);
824 if (columnMapping == null)
825 columnMapping = new DataColumnMapping (col.ColumnName, col.ColumnName);
826 tableMapping.ColumnMappings.Add (columnMapping);
829 ArrayList cmc = new ArrayList ();
830 foreach (DataColumn col in dataTable.Columns)
831 cmc.Add (new DataColumnMapping (col.ColumnName, col.ColumnName));
833 new DataTableMapping (
836 cmc.ToArray (typeof (DataColumnMapping)) as DataColumnMapping []);
838 /**end insert from another update**/
839 return Update (dataTable, tableMapping);
842 // All the batch methods, should be implemented, if supported,
843 // by individual providers
845 protected virtual int AddToBatch (IDbCommand command)
847 throw CreateMethodNotSupportedException ();
850 protected virtual void ClearBatch ()
852 throw CreateMethodNotSupportedException ();
855 protected virtual int ExecuteBatch ()
857 throw CreateMethodNotSupportedException ();
860 protected virtual IDataParameter GetBatchedParameter (int commandIdentifier, int parameterIndex)
862 throw CreateMethodNotSupportedException ();
865 protected virtual bool GetBatchedRecordsAffected (int commandIdentifier, out int recordsAffected, out Exception error)
872 protected virtual void InitializeBatching ()
874 throw CreateMethodNotSupportedException ();
877 protected virtual void TerminateBatching ()
879 throw CreateMethodNotSupportedException ();
882 Exception CreateMethodNotSupportedException ()
884 return new NotSupportedException ("Method is not supported.");
886 #endregion // Methods