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";
56 IDbCommand _selectCommand;
57 IDbCommand _updateCommand;
58 IDbCommand _deleteCommand;
59 IDbCommand _insertCommand;
66 protected DbDataAdapter()
70 protected DbDataAdapter(DbDataAdapter adapter) : base(adapter)
79 protected internal CommandBehavior FillCommandBehavior {
80 get { throw new NotImplementedException (); }
81 set { throw new NotImplementedException (); }
84 IDbCommand IDbDataAdapter.SelectCommand {
85 get { return _selectCommand; }
86 set { _selectCommand = value; }
89 IDbCommand IDbDataAdapter.UpdateCommand{
90 get { return _updateCommand; }
91 set { _updateCommand = value; }
94 IDbCommand IDbDataAdapter.DeleteCommand{
95 get { return _deleteCommand; }
96 set { _deleteCommand = value; }
99 IDbCommand IDbDataAdapter.InsertCommand{
100 get { return _insertCommand; }
101 set { _insertCommand = value; }
105 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
106 public DbCommand SelectCommand {
107 get { return (DbCommand) ((IDbDataAdapter) this).SelectCommand; }
108 set { ((IDbDataAdapter) this).SelectCommand = value; }
112 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
113 public DbCommand DeleteCommand {
114 get { return (DbCommand) ((IDbDataAdapter) this).DeleteCommand; }
115 set { ((IDbDataAdapter) this).DeleteCommand = value; }
119 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
120 public DbCommand InsertCommand {
121 get { return (DbCommand) ((IDbDataAdapter) this).InsertCommand; }
122 set { ((IDbDataAdapter) this).InsertCommand = value; }
126 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
127 public DbCommand UpdateCommand {
128 get { return (DbCommand) ((IDbDataAdapter) this).UpdateCommand; }
129 set { ((IDbDataAdapter) this).UpdateCommand = value; }
134 public virtual int UpdateBatchSize {
136 set { throw new NotSupportedException (); }
139 IDbCommand SelectCommand {
140 get { return ((IDbDataAdapter) this).SelectCommand; }
143 IDbCommand UpdateCommand {
144 get { return ((IDbDataAdapter) this).UpdateCommand; }
147 IDbCommand DeleteCommand {
148 get { return ((IDbDataAdapter) this).DeleteCommand; }
151 IDbCommand InsertCommand {
152 get { return ((IDbDataAdapter) this).InsertCommand; }
156 #endregion // Properties
160 #if ONLY_1_0 || ONLY_1_1
162 [DataCategory ("Fill")]
163 [DataSysDescription ("Event triggered when a recoverable error occurs during Fill.")]
164 public event FillErrorEventHandler FillError;
172 protected virtual RowUpdatedEventArgs CreateRowUpdatedEvent (DataRow dataRow, IDbCommand command,
173 StatementType statementType,
174 DataTableMapping tableMapping)
176 return new RowUpdatedEventArgs (dataRow, command, statementType, tableMapping);
179 protected virtual RowUpdatingEventArgs CreateRowUpdatingEvent (DataRow dataRow, IDbCommand command,
180 StatementType statementType,
181 DataTableMapping tableMapping)
183 return new RowUpdatingEventArgs (dataRow, command, statementType, tableMapping);
186 protected virtual void OnRowUpdated (RowUpdatedEventArgs value)
188 if (Events ["RowUpdated"] != null) {
189 Delegate [] rowUpdatedList = Events ["RowUpdated"].GetInvocationList ();
190 foreach (Delegate rowUpdated in rowUpdatedList) {
191 MethodInfo rowUpdatedMethod = rowUpdated.Method;
192 rowUpdatedMethod.Invoke (value, null);
197 protected virtual void OnRowUpdating (RowUpdatingEventArgs value)
199 if (Events ["RowUpdating"] != null) {
200 Delegate [] rowUpdatingList = Events ["RowUpdating"].GetInvocationList ();
201 foreach (Delegate rowUpdating in rowUpdatingList) {
202 MethodInfo rowUpdatingMethod = rowUpdating.Method;
203 rowUpdatingMethod.Invoke (value, null);
208 protected abstract RowUpdatedEventArgs CreateRowUpdatedEvent (DataRow dataRow, IDbCommand command,
209 StatementType statementType,
210 DataTableMapping tableMapping);
212 protected abstract RowUpdatingEventArgs CreateRowUpdatingEvent (DataRow dataRow, IDbCommand command,
213 StatementType statementType,
214 DataTableMapping tableMapping);
216 protected abstract void OnRowUpdated (RowUpdatedEventArgs value);
217 protected abstract void OnRowUpdating (RowUpdatingEventArgs value);
220 protected override void Dispose (bool disposing)
223 IDbDataAdapter da = (IDbDataAdapter) this;
224 if (da.SelectCommand != null) {
225 da.SelectCommand.Dispose();
226 da.SelectCommand = null;
228 if (da.InsertCommand != null) {
229 da.InsertCommand.Dispose();
230 da.InsertCommand = null;
232 if (da.UpdateCommand != null) {
233 da.UpdateCommand.Dispose();
234 da.UpdateCommand = null;
236 if (da.DeleteCommand != null) {
237 da.DeleteCommand.Dispose();
238 da.DeleteCommand = null;
243 public override int Fill (DataSet dataSet)
245 return Fill (dataSet, 0, 0, DefaultSourceTableName, ((IDbDataAdapter) this).SelectCommand, CommandBehavior.Default);
248 public int Fill (DataTable dataTable)
250 if (dataTable == null)
251 throw new ArgumentNullException ("DataTable");
253 return Fill (dataTable, ((IDbDataAdapter) this).SelectCommand, CommandBehavior.Default);
256 public int Fill (DataSet dataSet, string srcTable)
258 return Fill (dataSet, 0, 0, srcTable, ((IDbDataAdapter) this).SelectCommand, CommandBehavior.Default);
262 protected virtual int Fill (DataTable dataTable, IDataReader dataReader)
264 return base.FillInternal (dataTable, dataReader);
268 protected virtual int Fill (DataTable dataTable, IDbCommand command, CommandBehavior behavior)
270 CommandBehavior commandBehavior = behavior;
272 // first see that the connection is not close.
273 if (command.Connection.State == ConnectionState.Closed)
275 command.Connection.Open ();
276 commandBehavior |= CommandBehavior.CloseConnection;
278 return Fill (dataTable, command.ExecuteReader (commandBehavior));
281 public int Fill (DataSet dataSet, int startRecord, int maxRecords, string srcTable)
283 return this.Fill (dataSet, startRecord, maxRecords, srcTable, ((IDbDataAdapter) this).SelectCommand, CommandBehavior.Default);
288 public int Fill (int startRecord, int maxRecords, DataTable[] dataTables)
290 throw new NotImplementedException ();
294 protected virtual int Fill (DataTable[] dataTables, int startRecord, int maxRecords, IDbCommand command, CommandBehavior behavior)
296 throw new NotImplementedException ();
302 protected virtual int Fill (DataSet dataSet, string srcTable, IDataReader dataReader, int startRecord, int maxRecords)
304 return base.FillInternal (dataSet, srcTable, dataReader, startRecord, maxRecords);
308 protected virtual int Fill (DataSet dataSet, int startRecord, int maxRecords, string srcTable, IDbCommand command, CommandBehavior behavior)
310 if (command.Connection == null) {
311 throw new InvalidOperationException ("Connection state is closed");
313 if (MissingSchemaAction == MissingSchemaAction.AddWithKey)
314 behavior |= CommandBehavior.KeyInfo;
315 CommandBehavior commandBehavior = behavior;
317 if (command.Connection.State == ConnectionState.Closed) {
318 command.Connection.Open ();
319 commandBehavior |= CommandBehavior.CloseConnection;
321 return Fill (dataSet, srcTable, command.ExecuteReader (commandBehavior), startRecord, maxRecords);
326 /// Fills the given datatable using values from reader. if a value
327 /// for a column is null, that will be filled with default value.
329 /// <returns>No. of rows affected </returns>
330 internal static int FillFromReader (DataTable table,
335 LoadOption loadOption
338 if (reader.FieldCount == 0)
341 for (int i = 0; i < start; i++)
345 object [] values = new object [mapping.Length];
346 while (reader.Read () &&
347 (length == 0 || counter < length)) {
349 for (int i = 0 ; i < mapping.Length; i++)
350 values [i] = mapping [i] < 0 ? null : reader [mapping [i]];
352 table.BeginLoadData ();
353 table.LoadDataRow (values, loadOption);
354 table.EndLoadData ();
360 internal static int FillFromReader (DataTable table,
365 LoadOption loadOption,
366 FillErrorEventHandler errorHandler)
368 if (reader.FieldCount == 0)
371 for (int i = 0; i < start; i++)
375 object [] values = new object [mapping.Length];
376 while (reader.Read () &&
377 (length == 0 || counter < length)) {
379 for (int i = 0 ; i < mapping.Length; i++)
380 values [i] = mapping [i] < 0 ? null : reader [mapping [i]];
382 table.BeginLoadData ();
384 table.LoadDataRow (values, loadOption);
385 } catch (Exception e) {
386 FillErrorEventArgs args = new FillErrorEventArgs (table, values);
388 args.Continue = false;
389 errorHandler (table, args);
390 // if args.Continue is not set to true or if a handler is not set, rethrow the error..
394 table.EndLoadData ();
402 public override DataTable[] FillSchema (DataSet dataSet, SchemaType schemaType)
404 return FillSchema (dataSet, schemaType, ((IDbDataAdapter) this).SelectCommand, DefaultSourceTableName, CommandBehavior.Default);
407 public DataTable FillSchema (DataTable dataTable, SchemaType schemaType)
409 return FillSchema (dataTable, schemaType, ((IDbDataAdapter) this).SelectCommand, CommandBehavior.Default);
412 public DataTable[] FillSchema (DataSet dataSet, SchemaType schemaType, string srcTable)
414 return FillSchema (dataSet, schemaType, ((IDbDataAdapter) this).SelectCommand, srcTable, CommandBehavior.Default);
417 protected virtual DataTable FillSchema (DataTable dataTable, SchemaType schemaType, IDbCommand command, CommandBehavior behavior)
419 if (dataTable == null)
420 throw new ArgumentNullException ("DataTable");
422 behavior |= CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo;
423 if (command.Connection.State == ConnectionState.Closed) {
424 command.Connection.Open ();
425 behavior |= CommandBehavior.CloseConnection;
428 IDataReader reader = command.ExecuteReader (behavior);
431 string tableName = SetupSchema (schemaType, dataTable.TableName);
432 if (tableName != null)
434 // FillSchema should add the KeyInfo unless MissingSchemaAction
435 // is set to Ignore or Error.
436 MissingSchemaAction schemaAction = MissingSchemaAction;
437 if (!(schemaAction == MissingSchemaAction.Ignore ||
438 schemaAction == MissingSchemaAction.Error))
439 schemaAction = MissingSchemaAction.AddWithKey;
441 BuildSchema (reader, dataTable, schemaType, schemaAction,
442 MissingMappingAction, TableMappings);
452 protected virtual DataTable[] FillSchema (DataSet dataSet, SchemaType schemaType, IDbCommand command, string srcTable, CommandBehavior behavior)
455 throw new ArgumentNullException ("DataSet");
457 behavior |= CommandBehavior.SchemaOnly | CommandBehavior.KeyInfo;
458 if (command.Connection.State == ConnectionState.Closed) {
459 command.Connection.Open ();
460 behavior |= CommandBehavior.CloseConnection;
463 IDataReader reader = command.ExecuteReader (behavior);
464 ArrayList output = new ArrayList ();
465 string tableName = srcTable;
470 // FillSchema should add the KeyInfo unless MissingSchemaAction
471 // is set to Ignore or Error.
472 MissingSchemaAction schemaAction = MissingSchemaAction;
473 if (!(MissingSchemaAction == MissingSchemaAction.Ignore ||
474 MissingSchemaAction == MissingSchemaAction.Error))
475 schemaAction = MissingSchemaAction.AddWithKey;
478 tableName = SetupSchema (schemaType, tableName);
479 if (tableName != null)
481 if (dataSet.Tables.Contains (tableName))
482 table = dataSet.Tables [tableName];
485 // Do not create schema if MissingSchemAction is set to Ignore
486 if (this.MissingSchemaAction == MissingSchemaAction.Ignore)
488 table = dataSet.Tables.Add (tableName);
491 BuildSchema (reader, table, schemaType, schemaAction,
492 MissingMappingAction, TableMappings);
494 tableName = String.Format ("{0}{1}", srcTable, ++index);
496 }while (reader.NextResult ());
502 return (DataTable[]) output.ToArray (typeof (DataTable));
507 protected override DataTable FillSchema (DataTable dataTable, SchemaType schemaType, IDataReader dataReader)
509 throw new NotImplementedException ();
513 protected override DataTable[] FillSchema (DataSet dataSet, SchemaType schemaType, string srcTable, IDataReader dataReader)
515 throw new NotImplementedException ();
519 [EditorBrowsable (EditorBrowsableState.Advanced)]
520 public override IDataParameter[] GetFillParameters ()
522 IDataParameter[] parameters = new IDataParameter [SelectCommand.Parameters.Count];
523 SelectCommand.Parameters.CopyTo (parameters, 0);
528 object ICloneable.Clone ()
530 throw new NotImplementedException ();
533 public int Update (DataRow[] dataRows)
535 if (dataRows == null)
536 throw new ArgumentNullException("dataRows");
538 if (dataRows.Length == 0)
541 if (dataRows[0] == null)
542 throw new ArgumentException("dataRows[0].");
544 DataTable table = dataRows[0].Table;
546 throw new ArgumentException("table is null reference.");
548 // all rows must be in the same table
549 for (int i = 0; i < dataRows.Length; i++)
551 if (dataRows[i] == null)
552 throw new ArgumentException("dataRows[" + i + "].");
553 if (dataRows[i].Table != table)
554 throw new ArgumentException(
557 + "] is from a different DataTable than DataRow[0].");
560 // get table mapping for this rows
561 DataTableMapping tableMapping = TableMappings.GetByDataSetTable(table.TableName);
562 if (tableMapping == null)
564 tableMapping = DataTableMappingCollection.GetTableMappingBySchemaAction(
568 MissingMappingAction);
569 if (tableMapping != null) {
570 foreach (DataColumn col in table.Columns) {
571 if (tableMapping.ColumnMappings.IndexOf (col.ColumnName) >= 0)
573 DataColumnMapping columnMapping = DataColumnMappingCollection.GetColumnMappingBySchemaAction (tableMapping.ColumnMappings, col.ColumnName, MissingMappingAction);
574 if (columnMapping == null)
575 columnMapping = new DataColumnMapping (col.ColumnName, col.ColumnName);
576 tableMapping.ColumnMappings.Add (columnMapping);
579 ArrayList cmc = new ArrayList ();
580 foreach (DataColumn col in table.Columns)
581 cmc.Add (new DataColumnMapping (col.ColumnName, col.ColumnName));
583 new DataTableMapping (
586 cmc.ToArray (typeof (DataColumnMapping)) as DataColumnMapping []);
590 DataRow[] copy = table.NewRowArray(dataRows.Length);
591 Array.Copy(dataRows, 0, copy, 0, dataRows.Length);
592 return Update(copy, tableMapping);
595 public override int Update (DataSet dataSet)
597 return Update (dataSet, DefaultSourceTableName);
600 public int Update (DataTable dataTable)
603 int index = TableMappings.IndexOfDataSetTable (dataTable.TableName);
605 throw new ArgumentException ();
606 return Update (dataTable, TableMappings [index]);
608 DataTableMapping tableMapping = TableMappings.GetByDataSetTable (dataTable.TableName);
609 if (tableMapping == null)
611 tableMapping = DataTableMappingCollection.GetTableMappingBySchemaAction (
615 MissingMappingAction);
616 if (tableMapping != null) {
617 foreach (DataColumn col in dataTable.Columns) {
618 if (tableMapping.ColumnMappings.IndexOf (col.ColumnName) >= 0)
620 DataColumnMapping columnMapping = DataColumnMappingCollection.GetColumnMappingBySchemaAction (tableMapping.ColumnMappings, col.ColumnName, MissingMappingAction);
621 if (columnMapping == null)
622 columnMapping = new DataColumnMapping (col.ColumnName, col.ColumnName);
623 tableMapping.ColumnMappings.Add (columnMapping);
626 ArrayList cmc = new ArrayList ();
627 foreach (DataColumn col in dataTable.Columns)
628 cmc.Add (new DataColumnMapping (col.ColumnName, col.ColumnName));
630 new DataTableMapping (
633 cmc.ToArray (typeof (DataColumnMapping)) as DataColumnMapping []);
636 return Update (dataTable, tableMapping);
639 private int Update (DataTable dataTable, DataTableMapping tableMapping)
641 DataRow[] rows = dataTable.NewRowArray(dataTable.Rows.Count);
642 dataTable.Rows.CopyTo (rows, 0);
643 return Update (rows, tableMapping);
646 protected virtual int Update (DataRow[] dataRows, DataTableMapping tableMapping)
649 foreach (DataRow row in dataRows) {
650 StatementType statementType = StatementType.Update;
651 IDbCommand command = null;
652 string commandName = String.Empty;
654 switch (row.RowState) {
655 case DataRowState.Added:
656 statementType = StatementType.Insert;
657 command = ((IDbDataAdapter) this).InsertCommand;
658 commandName = "Insert";
660 case DataRowState.Deleted:
661 statementType = StatementType.Delete;
662 command = ((IDbDataAdapter) this).DeleteCommand;
663 commandName = "Delete";
665 case DataRowState.Modified:
666 statementType = StatementType.Update;
667 command = ((IDbDataAdapter) this).UpdateCommand;
668 commandName = "Update";
670 case DataRowState.Unchanged:
671 case DataRowState.Detached:
675 RowUpdatingEventArgs argsUpdating = CreateRowUpdatingEvent (row, command, statementType, tableMapping);
677 OnRowUpdating (argsUpdating);
678 switch (argsUpdating.Status) {
679 case UpdateStatus.Continue :
680 //continue in update operation
682 case UpdateStatus.ErrorsOccurred :
683 if (argsUpdating.Errors == null) {
684 argsUpdating.Errors = ExceptionHelper.RowUpdatedError();
686 row.RowError += argsUpdating.Errors.Message;
687 if (!ContinueUpdateOnError) {
688 throw argsUpdating.Errors;
691 case UpdateStatus.SkipAllRemainingRows :
693 case UpdateStatus.SkipCurrentRow :
697 throw ExceptionHelper.InvalidUpdateStatus (argsUpdating.Status);
699 command = argsUpdating.Command;
701 if (command != null) {
702 DataColumnMappingCollection columnMappings = tableMapping.ColumnMappings;
703 IDataParameter nullCheckParam = null;
704 foreach (IDataParameter parameter in command.Parameters) {
705 if ((parameter.Direction & ParameterDirection.Input) != 0) {
706 string dsColumnName = parameter.SourceColumn;
707 if (columnMappings.Contains(parameter.SourceColumn))
708 dsColumnName = columnMappings [parameter.SourceColumn].DataSetColumn;
709 if (dsColumnName == null || dsColumnName.Length <= 0) {
710 nullCheckParam = parameter;
714 DataRowVersion rowVersion = parameter.SourceVersion;
715 // Parameter version is ignored for non-update commands
716 if (statementType == StatementType.Delete)
717 rowVersion = DataRowVersion.Original;
719 parameter.Value = row [dsColumnName, rowVersion];
720 if (nullCheckParam != null && (parameter.Value != null
721 && parameter.Value != DBNull.Value)) {
722 nullCheckParam.Value = 0;
723 nullCheckParam = null;
729 catch (Exception e) {
730 argsUpdating.Errors = e;
731 argsUpdating.Status = UpdateStatus.ErrorsOccurred;
735 IDataReader reader = null;
737 if (command == null) {
738 throw ExceptionHelper.UpdateRequiresCommand (commandName);
741 CommandBehavior commandBehavior = CommandBehavior.Default;
742 if (command.Connection.State == ConnectionState.Closed) {
743 command.Connection.Open ();
744 commandBehavior |= CommandBehavior.CloseConnection;
747 // use ExecuteReader because we want to use the commandbehavior parameter.
748 // so the connection will be closed if needed.
749 reader = command.ExecuteReader (commandBehavior);
751 // update the current row, if the update command returns any resultset
752 // ignore other than the first record.
753 DataColumnMappingCollection columnMappings = tableMapping.ColumnMappings;
755 if (command.UpdatedRowSource == UpdateRowSource.Both ||
756 command.UpdatedRowSource == UpdateRowSource.FirstReturnedRecord) {
758 DataTable retSchema = reader.GetSchemaTable ();
759 foreach (DataRow dr in retSchema.Rows) {
760 string columnName = dr ["ColumnName"].ToString ();
761 string dstColumnName = columnName;
762 if (columnMappings != null &&
763 columnMappings.Contains(columnName))
764 dstColumnName = columnMappings [dstColumnName].DataSetColumn;
765 DataColumn dstColumn = row.Table.Columns [dstColumnName];
766 if (dstColumn == null
767 || (dstColumn.Expression != null
768 && dstColumn.Expression.Length > 0))
770 // info from : http://www.error-bank.com/microsoft.public.dotnet.framework.windowsforms.databinding/
771 // _35_hcsyiv0dha.2328@tk2msftngp10.phx.gbl_Thread.aspx
772 // disable readonly for non-expression columns.
773 bool readOnlyState = dstColumn.ReadOnly;
774 dstColumn.ReadOnly = false;
776 row [dstColumnName] = reader [columnName];
778 dstColumn.ReadOnly = readOnlyState;
785 int tmp = reader.RecordsAffected; // records affected is valid only after closing reader
786 // if the execute does not effect any rows we throw an exception.
788 throw new DBConcurrencyException("Concurrency violation: the " +
789 commandName +"Command affected 0 records.");
792 if (command.UpdatedRowSource == UpdateRowSource.Both ||
793 command.UpdatedRowSource == UpdateRowSource.OutputParameters) {
794 // Update output parameters to row values
795 foreach (IDataParameter parameter in command.Parameters) {
796 if (parameter.Direction != ParameterDirection.InputOutput
797 && parameter.Direction != ParameterDirection.Output
798 && parameter.Direction != ParameterDirection.ReturnValue)
801 string dsColumnName = parameter.SourceColumn;
802 if (columnMappings != null &&
803 columnMappings.Contains(parameter.SourceColumn))
804 dsColumnName = columnMappings [parameter.SourceColumn].DataSetColumn;
805 DataColumn dstColumn = row.Table.Columns [dsColumnName];
806 if (dstColumn == null
807 || (dstColumn.Expression != null
808 && dstColumn.Expression.Length > 0))
810 bool readOnlyState = dstColumn.ReadOnly;
811 dstColumn.ReadOnly = false;
813 row [dsColumnName] = parameter.Value;
815 dstColumn.ReadOnly = readOnlyState;
821 RowUpdatedEventArgs updatedArgs = CreateRowUpdatedEvent (row, command, statementType, tableMapping);
822 OnRowUpdated (updatedArgs);
823 switch (updatedArgs.Status) {
824 case UpdateStatus.Continue:
826 case UpdateStatus.ErrorsOccurred:
827 if (updatedArgs.Errors == null) {
828 updatedArgs.Errors = ExceptionHelper.RowUpdatedError();
830 row.RowError += updatedArgs.Errors.Message;
831 if (!ContinueUpdateOnError) {
832 throw updatedArgs.Errors;
835 case UpdateStatus.SkipCurrentRow:
837 case UpdateStatus.SkipAllRemainingRows:
841 if (!AcceptChangesDuringUpdate)
844 row.AcceptChanges ();
845 } catch(Exception e) {
846 row.RowError = e.Message;
847 if (!ContinueUpdateOnError) {
851 if (reader != null && ! reader.IsClosed) {
859 public int Update (DataSet dataSet, string sourceTable)
861 MissingMappingAction mappingAction = MissingMappingAction;
863 if (mappingAction == MissingMappingAction.Ignore)
864 mappingAction = MissingMappingAction.Error;
866 DataTableMapping tableMapping = DataTableMappingCollection.GetTableMappingBySchemaAction (TableMappings, sourceTable, sourceTable, mappingAction);
868 DataTable dataTable = dataSet.Tables[tableMapping.DataSetTable];
869 if (dataTable == null)
870 throw new ArgumentException (String.Format ("Missing table {0}",
872 return Update (dataTable, tableMapping);
876 // All the batch methods, should be implemented, if supported,
877 // by individual providers
879 protected virtual int AddToBatch (IDbCommand cmd)
881 throw new NotSupportedException ();
884 protected virtual void ClearBatch ()
886 throw new NotSupportedException ();
889 protected virtual int ExecuteBatch ()
891 throw new NotSupportedException ();
894 protected virtual IDataParameter GetBatchedParameter (int commandIdentifier, int parameterIdentifer)
896 throw new NotSupportedException ();
899 protected virtual void InitializeBatching ()
901 throw new NotSupportedException ();
904 protected virtual void TerminateBatching ()
906 throw new NotSupportedException ();
910 #if ONLY_1_0 || ONLY_1_1
911 internal override void OnFillErrorInternal (FillErrorEventArgs value)
916 protected virtual void OnFillError (FillErrorEventArgs value)
918 if (FillError != null)
919 FillError (this, value);
923 #endregion // Methods