Implementing a DataAdapter
If you are implementing the complete set of .NET Framework data provider interfaces, the implementation of the DataAdapter requires minimal coding, as the System.Data.Common.DbDataAdapter class provides most of the implementation.
To use DbDataAdapter
Provide implementations of IDbConnection, IDbCommand, IDataReader, and so on. The DbDataAdapter class leverages these components in its implementation.
Create a class that inherits from DbDataAdapter and IDbDataAdapter. For example:
Public Class TemplateDataAdapter Inherits DbDataAdapter Implements IDbDataAdapter End Class [C#]public class TemplateDataAdapter : DbDataAdapter, IDbDataAdapter { }
Implement the IDbDataAdapter interface, and provide property and method implementations that supply "strong typing". This allows users of your .NET Framework data provider to reference the objects you provide directly, instead of through interfaces such as IDbCommand.
The following example shows a SelectCommand property that returns a strongly typed TemplateCommand. The TemplateDataAdapter.SelectCommand property will return an IDbCommand when the TemplateDataAdapter is cast as IDbDataAdapter.
Private m_selectCommand As TemplateCommand Property IDbDataAdapterSelectCommand As IDbCommand Implements IDbDataAdapter.SelectCommand Get Return m_selectCommand End Get Set m_selectCommand = CType(value, TemplateCommand) End Set End Property Public Property SelectCommand As TemplateCommand Get Return m_selectCommand End Get Set m_selectCommand = value End Set End Property [C#]private TemplateCommand m_selectCommand; public TemplateCommand SelectCommand { get { return m_selectCommand; } set { m_selectCommand = value; } } IDbCommand IDbDataAdapter.SelectCommand { get { return m_selectCommand; } set { m_selectCommand = (TemplateCommand)value; } }
Implement provider-specific versions of RowUpdatedEventArgs and RowUpdatingEventArgs, as well as associated event handler types (this is boilerplate code). The overloaded event types also exist to provide strong typing, allowing both the event object itself as well as appropriate properties (such as the Command property) to be exposed in a strongly typed manner. For example:
Public Class TemplateRowUpdatingEventArgs Inherits RowUpdatingEventArgs Public Sub New(row As DataRow, command As IDbCommand, statementType As StatementType, tableMapping As DataTableMapping) MyBase.New(row, command, statementType, tableMapping) End Sub ' Hide the inherited implementation of the command property. Public Shadows Property Command As TemplateCommand Get Return CType(MyBase.Command, TemplateCommand) End Get Set MyBase.Command = value End Set End Property End Class Public Class TemplateRowUpdatedEventArgs Inherits RowUpdatedEventArgs Public Sub New(row As DataRow, command As IDbCommand, statementType As StatementType, tableMapping As DataTableMapping) MyBase.New(row, command, statementType, tableMapping) End Sub ' Hide the inherited implementation of the command property. Public Shadows ReadOnly Property Command As TemplateCommand Get Return CType(MyBase.Command, TemplateCommand) End Get End Property End Class [C#]public class TemplateRowUpdatingEventArgs : RowUpdatingEventArgs { public TemplateRowUpdatingEventArgs(DataRow row, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) : base(row, command, statementType, tableMapping) { } // Hide the inherited implementation of the command property. new public TemplateCommand Command { get { return (TemplateCommand)base.Command; } set { base.Command = value; } } } public class TemplateRowUpdatedEventArgs : RowUpdatedEventArgs { public TemplateRowUpdatedEventArgs(DataRow row, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) : base(row, command, statementType, tableMapping) { } // Hide the inherited implementation of the command property. new public TemplateCommand Command { get { return (TemplateCommand)base.Command; } } }
Implement the abstract methods of the DbDataAdapter. For example:
Protected Overrides Function CreateRowUpdatedEvent(dataRow As DataRow, command As IDbCommand, statementType As StatementType, tableMapping As DataTableMapping) As RowUpdatedEventArgs Return New TemplateRowUpdatedEventArgs(dataRow, command, statementType, tableMapping) End Function Protected Overrides Function CreateRowUpdatingEvent(dataRow As DataRow, command As IDbCommand, statementType As StatementType, tableMapping As DataTableMapping) As RowUpdatingEventArgs Return New TemplateRowUpdatingEventArgs(dataRow, command, statementType, tableMapping) End Function Protected Overrides Sub OnRowUpdating(value As RowUpdatingEventArgs) Dim handler As TemplateRowUpdatingEventHandler = CType(Events(EventRowUpdating), TemplateRowUpdatingEventHandler) If Not handler Is Nothing And value.GetType() Is Type.GetType("TemplateRowUpdatingEventArgs") Then handler(Me, CType(value, TemplateRowUpdatingEventArgs)) End If End Sub Protected Overrides Sub OnRowUpdated(value As RowUpdatedEventArgs) Dim handler As TemplateRowUpdatedEventHandler = CType(Events(EventRowUpdated), TemplateRowUpdatedEventHandler) If Not handler Is Nothing And value.GetType() Is Type.GetType("TemplateRowUpdatedEventArgs") Then handler(Me, CType(value, TemplateRowUpdatedEventArgs)) End If End Sub [C#]override protected RowUpdatedEventArgs CreateRowUpdatedEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) { return new TemplateRowUpdatedEventArgs(dataRow, command, statementType, tableMapping); } override protected RowUpdatingEventArgs CreateRowUpdatingEvent(DataRow dataRow, IDbCommand command, StatementType statementType, DataTableMapping tableMapping) { return new TemplateRowUpdatingEventArgs(dataRow, command, statementType, tableMapping); } override protected void OnRowUpdating(RowUpdatingEventArgs value) { TemplateRowUpdatingEventHandler handler = (TemplateRowUpdatingEventHandler) Events[EventRowUpdating]; if ((null != handler) && (value is TemplateRowUpdatingEventArgs)) { handler(this, (TemplateRowUpdatingEventArgs) value); } } override protected void OnRowUpdated(RowUpdatedEventArgs value) { TemplateRowUpdatedEventHandler handler = (TemplateRowUpdatedEventHandler) Events[EventRowUpdated]; if ((null != handler) && (value is TemplateRowUpdatedEventArgs)) { handler(this, (TemplateRowUpdatedEventArgs) value); } }
Finish implementing events on the DbDataAdapter derived class as in the following example. Note that the events are a part of the TemplateDataAdapter class, and the delegates are a part of the namespace.
Public Event RowUpdating As TemplateRowUpdatingEventHandler Public Event RowUpdated As TemplateRowUpdatedEventHandler Public Delegate Sub TemplateRowUpdatingEventHandler(sender As Object, e As TemplateRowUpdatingEventArgs) Public Delegate Sub TemplateRowUpdatedEventHandler(sender As Object, e As TemplateRowUpdatedEventArgs) [C#]public event TemplateRowUpdatingEventHandler RowUpdating { add { Events.AddHandler(EventRowUpdating, value); } remove { Events.RemoveHandler(EventRowUpdating, value); } } public event TemplateRowUpdatedEventHandler RowUpdated { add { Events.AddHandler(EventRowUpdated, value); } remove { Events.RemoveHandler(EventRowUpdated, value); } } public delegate void TemplateRowUpdatingEventHandler(object sender, TemplateRowUpdatingEventArgs e); public delegate void TemplateRowUpdatedEventHandler(object sender, TemplateRowUpdatedEventArgs e);
The following topics contain sample code for an implementation of a DataAdapter object.
For a sample Visual Basic implementation:
For a sample C# implementation:
See Also
Implementing a .NET Framework Data Provider | Sample .NET Framework Data Provider