如果正在实现整组 .NET 数据提供程序接口,DataAdapter 的实现将需要最少的编码,因为 System.Data.Common.DbDataAdapter 类会提供实现的大部分内容。

使用 DbDataAdapter

  1. 提供 IDbConnectionIDbCommandIDataReader 等的实现。DbDataAdapter 类在其实现中利用这些组件。
  2. 创建一个从 DbDataAdapterIDbDataAdapter 继承的类。例如:

    Public Class TemplateDataAdapter
      Inherits DbDataAdapter
      Implements IDbDataAdapter
    End Class

    public class TemplateDataAdapter : DbDataAdapter, IDbDataAdapter
    {
    }

  3. 实现 IDbDataAdapter 接口,并提供可提供“强类型”的属性和方法实现。这样,.NET 数据提供程序的用户就可以直接引用您提供的对象,而不是通过 IDbCommand 等接口来引用。

    以下示例显示一个返回强类型 TemplateCommand 的 SelectCommand 属性。在 C# 中,该属性经过重载,也可以返回 IDbCommand 对象。请注意,Visual Basic .NET 不允许重载只有返回类型不同的属性,因此不能同时返回 IDbCommand 和您自己的强类型 TemplateCommand。

    Private m_selectCommand As TemplateCommand

    Public Property SelectCommand As IDbCommand Implements IDbDataAdapter.SelectCommand 
      Get
        Return m_selectCommand
      End Get
      Set
        m_selectCommand = CType(value, TemplateCommand)
      End Set
    End Property

    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; }
    }

  4. 实现 RowUpdatedEventArgsRowUpdatingEventArgs 的提供程序特定版本以及关联的事件处理程序类型(这是样板代码)。重载事件类型的存在也是为了提供强类型,以允许事件对象本身以及合适的属性(如 Command 属性)以强类型方式公开。例如:

    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

    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; }
      }
    }

  5. 实现 DbDataAdapter 的抽象方法。例如:

    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

    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);
      }
    }

  6. 如以下示例所示,在 DbDataAdapter 派生类上完成事件的实现。请注意,事件是 TemplateDataAdapter 类的一部分,而委托是命名空间的一部分。

    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)

    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);

以下主题包含 DataAdapter 对象的实现的示例代码。

对于示例 Visual Basic 实现:

对于示例 C# 实现: