變更類型化資料集的 TableAdapter 基項

頁面創建日期 :

建立與產生類型化資料集的代碼

類型化 DataSet 允許您創建基於 SQL 的每列類型資訊的 DataTable,並使用 TableAdapter 簡化與 DB 的資料互動。

由於此處不是創建類型化 DataSet 的目標,因此讓我們快速創建 DataSet,而資料庫和表是準備的。 您可以隨意佈局表。

首先,將 DataSet 作為新專案添加到專案中。 名字可以做任何事情,但在這裡,它保持原樣。

打開 DataSet 並從設計器添加 TableAdapter。

嚮導將生成DataTable和TableAdapter。

使用您建立的 DataTable 與 TableAdapter 從資料庫中檢索與使用紀錄的範例可能如下所示: (這隻是一個例子)

public Form1()
{
  InitializeComponent();

  using (var adapter = new 金額集計TestTableAdapter())
  {
    var table = adapter.GetData();

    foreach (var row in table)
    {
      Trace.WriteLine(string.Format("{0}:{1}", row.年月, row.金額));
    }
  }
}

通常,在使用此 DataSet 的專案中,只有一個表,並且創建許多包含表或多個表的數據集。 我認為,如果發生這種情況,我們想到的是處理的共性。 例如,您可以動態更改內部使用的 SQL 以更改記錄檢索條件。

但是,實際上,從 DataSet 創建的 TableAdapter 類是自動生成的代碼。 此外,由於此 TableAdapter 類是元件類繼承的,因此沒有真正通用的方法或屬性。 不能將基類傳遞給方法,並調用與 TableAdapter 相關的操作。

此外,內部使用的 SQL 和用於訪問資料庫的 SqlDataAdapter 等在受保護中聲明,因此不能從外部觸摸。

但是,您可以按照聲明方式訪問在受保護中聲明的方法和屬性,也可以創建繼承 TableAdapter 類的類,並且此 TableAdapter 類具有部分修飾符,因此可以通過聲明其他方法和屬性來擴展處理。 您還可以建立新屬性以取得內部屬性,如以下代碼所示:

using System.Data.SqlClient;
namespace DataSetBaseAdapter {
    public partial class DataSet1 {
    }
}

namespace DataSetBaseAdapter.DataSet1TableAdapters
{
  public partial class 金額集計TestTableAdapter
  {
    public SqlDataAdapter InnerAdapter
    {
      get { return Adapter; }
    }
  }
}

實際上,此 TableAdapter 允許您訪問擴展的屬性。

但是,由於可以存取內部屬性,因此處理不是通用的,您仍必須為每個創建的 DataSet 編寫代碼。

變更 TableAdapter 基項

如前所述,TableAdapter 類繼承了元件類,因此很難使處理變得通用。 如果更改類繼承的代碼部分,則代碼是自動生成的,因此再次更新 DataSet 將返回代碼。 如果可以,可以編寫一個將介面繼承到另一個檔的部件類,但這沒有意義,因為您只需編寫最終創建的 TableAdapter 的數量。

實際上,有一種機制可以更改此 TableAdapter 的繼承類。 我想解釋一下這個程式。

首先,創建要繼承的類。 由於 TableAdapter 最初繼承元件類,因此您創建的類也繼承元件類。 現在,我們將編寫一個要通用的代碼,但讓我們只創建一個類。 將命名空間與您創建的命名空間匹配。

using System.ComponentModel;

namespace DataSetBaseAdapter
{
  public class BaseAdapter : Component
  {
  }
}

然後,打開 DataSet 設計器並選擇您建立的 TableAdapter。

右鍵單擊以打開屬性。 屬性稱為 BaseClass,最初應為 System.ComponentModel.Component。 將其重寫為剛剛創建的類。 寫所有內容,包括命名空間。

保存後,您將看到 TableAdapter 的基類已更改。 通過為每個 TableAdapter 設定此設定,可以將常見操作寫入基類。

例如,如果要造訪內部 SQL 或 SqlDataAdapter,請執行以下操作: 自動建立的適配器和 CommandCollection 是繼承類創建的屬性,不能直接從繼承者處聯繫。 以下代碼使用反射強制訪問。

using System.ComponentModel;
using System.Data.SqlClient;
using System.Reflection;

namespace DataSetBaseAdapter
{
  public class BaseAdapter : Component
  {
    public SqlDataAdapter InnerAdapter
    {
      get
      {
        return (SqlDataAdapter)GetType().GetProperty("Adapter",
          BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this, null);
      }
    }

    public SqlCommand[] InnerCommandCollection
    {
      get
      {
        return (SqlCommand[])GetType().GetProperty("CommandCollection",
          BindingFlags.NonPublic | BindingFlags.Instance).GetValue(this, null);
      }
    }
  }
}

您可以看到,實際上,您可以使用 TableAdapter 訪問來源類的屬性。