Ändra basklassen för en TableAdapter i en maskinskriven DataSet

Datum för skapande av sida :

Kod för att skapa och generera en maskinskriven DataSet

Med en maskinskriven DataSet kan du skapa en DataTable som har typinformation för varje kolumn baserat på SQL, eller en TableAdapter som förenklar datainteraktionen med DB baserat på en maskinskriven DataTable.

Eftersom syftet inte är att skapa en maskinskriven DataSet här, låt oss snabbt skapa en DataSet med databasen och tabellen redo för nu. Du kan också göra vad du vill lägga ut bordet.

Det första steget är att lägga till en DataSet som ett nytt objekt i projektet. Namnet är allt annat än det är kvar här.

Öppna DataSet och lägg till en TableAdapter från designern.

Följ guiden för att skapa en DataTable och A TableAdapter.

Jag tror att följande formulär kan vara ett exempel på att hämta och använda poster från databasen med hjälp av DataTable och TableAdapter som du skapade. (Detta är bara ett exempel.)

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.金額));
    }
  }
}

Vanligtvis har ett projekt som använder den här DataSet mindre än en tabell och du skapar många DataSets som kombinerar antalet tabeller eller flera tabeller. Jag tror att det är en gemensam läggning av behandlingen att komma upp när det händer. Du kanske till exempel vill ändra SQL dynamiskt som används internt för att ändra villkoren för att hämta poster.

Klassen TableAdapter som skapats från DataSet genereras dock automatiskt av koden. Eftersom den här klassen TableAdapter ärver klassen Component finns det inga metoder eller egenskaper som kan användas i verkligt vanliga. Du kan inte skicka en basklass till en metod för att anropa en tabelladapterrelaterad åtgärd.

Dessutom sql används internt, sqldataadapter används för att komma åt databasen, etc. deklareras i skyddade, så du kan inte röra dem från utsidan.

När du deklarerar för metoder och egenskaper som deklarerats i skyddad kan du dock trycka på dem genom att skapa en klass som ärver klassen TableAdapter, och den här klassen TableAdapter har en partiell modifierare, så att du kan deklarera en annan metod eller egenskap för att utöka processen. Du kan också skapa en ny egenskap för att hämta den interna egenskapen, som i följande kod:

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

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

Du kan faktiskt använda den här TableAdapter för att se att du har tillgång till de utökade egenskaperna.

Att komma åt interna egenskaper innebär dock inte att processen är vanlig och att du fortfarande måste skriva kod för varje DataSet som du skapar.

Ändra basklassen för en TableAdapter

Som tidigare nämnts ärver klassen TableAdapter klassen Component, vilket gör det svårt att dela bearbetning. Om du ändrar den del av koden som ärver en klass genereras koden automatiskt, så om du uppdaterar DataSet igen returneras koden. Om du kan kan du skriva en partiell klass som ärver gränssnittet i en separat fil, men det är inte mycket meningsfullt eftersom du måste skriva så många TableAdapters som du har skapat.

I själva verket finns det en mekanism för att ändra den ärva klassen i denna TableAdapter. Jag skulle vilja förklara proceduren.

Skapa först den klass som du vill ärva. TableAdapter ärvde ursprungligen klassen Component, så du bör ärva klassen Component även om du skapar den. Jag ska skriva koden jag vill dela här, men jag ska bara skriva en klass. Matcha namnområdet med det du skapade.

using System.ComponentModel;

namespace DataSetBaseAdapter
{
  public class BaseAdapter : Component
  {
  }
}

Öppna sedan DataSet-designern och välj den TableAdapter som du skapade.

Högerklicka för att öppna egenskapen. Det finns en egenskap som heter BaseClass, som först ska vara "System.ComponentModel.Component". Skriv om detta till den klass som du just skapade. Jag skriver allt, inklusive namnområdet.

Om du sparar den ser du att basklassen för TableAdapter har ändrats. Genom att ställa in detta på varje TableAdapter kan du skriva vanlig bearbetning till basklassen.

Om du till exempel vill komma åt en intern SQL eller SQLDataAdapter skriver du: Kort och CommandCollections som skapas automatiskt är bara egenskaper som skapas av arvtagaren, så att de inte kan röras direkt från arvtagaren. Följande kod använder reflektion för att tvinga åtkomst.

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

Du kan se att du faktiskt kan använda TableAdapter för att komma åt egenskaperna för den ärvda klassen.