Gewusst wie: Implementieren eine Hilfsklasse DataSet JOIN in Visual C# .NET

Eine Microsoft Visual Basic .NET Version dieses Artikels finden Sie unter

325688 so wird's gemacht: implementieren eine Hilfsklasse DataSet JOIN in Visual Basic .NET
Hinweis: Dieser Artikel gehört zu einer Reihe von DataSetHelper -Artikel. In diesem Artikel mit dem Code, das andere DataSetHelper -Artikel aufgeführt ist zu einer einzelnen Klasse mit einem umfassenderen Funktionssatz gemäß können den Code in der DataSetHelper -Klasse zusammengeführt werden.


Dieser Artikel bezieht sich auf die folgenden Namespaces für Microsoft.NET Framework-Klassenbibliothek:
  • System.Data

IN DIESER AUFGABE

Zusammenfassung

Dieser Artikel beschreibt die Implementierung und Verwendung einer DataSetHelper -Klasse, die enthält Beispielcode aus zwei oder mehr verknüpfte DataTable Definitionen ein DataTable -Objekt erstellen und Kopieren von Datensätzen, die sortiert und gefiltert werden von der DataTable -Objekte zum Ziel DataTable.

Dazu verwenden Sie die folgenden öffentlichen Methoden:

  • CreateJoinTable
  • InsertJoinInto
  • SelectJoinInto
SelectJoinInto -Methode ruft CreateJoinTable und InsertJoinInto -Methoden. Eine private Methode und Daten Hilfsmember können Sie die analysierten Liste speichern.

DataSetHelper -Klasse enthält eine Membervariable DataSet . Optional können Sie ein vorhandenes DataSet DataSet -Membervariable zuweisen. Weist die Membervariable auf ein gültiges DataSetwerden alle DataTable -Objekte, die CreateJoinTable oder die SelectJoinInto -Methode erstellt das DataSethinzugefügt. In beiden Fällen gibt der Methodenaufruf einen Verweis auf das DataTable -Objekt. InsertJoinInto -Methode erfordert ein Ziel DataTable und nicht zurück.

Weitere Informationen zu DataSet -Objekten finden Sie der Microsoft Knowledge Base:

313485 INFO: Wegweiser für ADO.NET DataSet DataView und DataViewManager

Voraussetzungen

Die folgende Liste führt die empfohlene Hardware, Software, Netzwerkinfrastruktur und Servicepacks auf, die benötigt werden:

  • Microsoft Windows XP, Windows 2000 oder Windows NT 4.0 Servicepack 6a
  • Microsoft Visual Studio .NET
Es wird vorausgesetzt, dass Sie mit folgenden Themen vertraut sind:

  • Visual C# .NET syntax
  • ADO.NET-Grundlagen und-Syntax

DataSetHelper-Shell-Klasse

Der Code in diesem Abschnitt deklariert die Shell-Klasse, DataSetHelper -Artikel Methoden und Membervariablen hinzufügen.
  1. Starten Sie Visual Studio .NET.
  2. Klicken Sie im Menü Datei auf neu und klicken Sie dann auf Projekt.
  3. Klicken Sie im Dialogfeld Neues Projekt klicken Sie unter Projekttypenauf Visual C#-Projekte , und klicken Sie unter Vorlagenauf Klassenbibliothek .
  4. Geben Sie im Feld Name DataSetHelper.
  5. Ersetzen Sie den Klassencode durch folgenden Code:
    public class DataSetHelper{
    public DataSet ds;

    public DataSetHelper(ref DataSet DataSet)
    {
    ds = DataSet;
    }
    public DataSetHelper()
    {
    ds = null;
    }
    }

    Zwei Überladung des Konstruktors können Sie eine Instanz der Klasse mit oder ohne einen Verweis auf ein gültiges DataSeterstellen. Für eine Klasse, die einen Verweis auf ein gültiges DataSetenthält, werden die DataTable -Objekte, die die Methoden zurückgeben DataSetauch automatisch hinzugefügt.

Feld Liste Parser

Dieser Abschnitt enthält den Code für ein Feld Liste Parser. Die analysierte Struktur wird verwendet, damit CreateJoinTable und InsertJoinInto -Methoden keinen Analysepunkt Feldliste. Diese Methoden müssen die Feldliste weiterhin, wenn sie die SelectJoinInto -Methode oder aus eigenem Code aufgerufen werden. Die analysierten Feldliste und nicht verarbeitete Feldliste werden in privaten Membervariablen der DataSetHelper -Klasse gespeichert.

  1. Fügen Sie die folgende Klassendefinition Private DataSetHelper -Klasse, die im Abschnitt "DataSetHelper-Shell-Klasse" erstellt:
    private class FieldInfo{
    public string RelationName;
    public string FieldName;//source table field name
    public string FieldAlias;//destination table field name
    public string Aggregate;
    }

    Hinweis: Diese Klasse ist für andere DataSetHelper -Artikel und enthält einige Felder, die in diesem Artikel nicht verwendet.

  2. Die Klassendefinition unmittelbar hinter der Deklaration DataSet die folgenden privaten Membervariablen hinzufügen:
    private System.Collections.ArrayList m_FieldInfo; private string m_FieldList; 
  3. Fügen Sie die folgende Private Methode der Klassendefinition. Diese Methode ist dieselbe Methode, die in anderen DataSetHelper -Artikel verwendet wird.
    private void ParseFieldList(string FieldList, bool AllowRelation){
    /*
    * This code parses FieldList into FieldInfo objects and then
    * adds them to the m_FieldInfo private member
    *
    * FieldList systax: [relationname.]fieldname[ alias], ...
    */
    if (m_FieldList == FieldList) return;
    m_FieldInfo = new System.Collections.ArrayList();
    m_FieldList = FieldList;
    FieldInfo Field; string[] FieldParts;
    string[] Fields=FieldList.Split(',');
    int i;
    for (i=0; i<=Fields.Length-1; i++)
    {
    Field=new FieldInfo();
    //parse FieldAlias
    FieldParts = Fields[i].Trim().Split(' ');
    switch (FieldParts.Length)
    {
    case 1:
    //to be set at the end of the loop
    break;
    case 2:
    Field.FieldAlias=FieldParts[1];
    break;
    default:
    throw new Exception("Too many spaces in field definition: '" + Fields[i] + "'.");
    }
    //parse FieldName and RelationName
    FieldParts = FieldParts[0].Split('.');
    switch (FieldParts.Length)
    {
    case 1:
    Field.FieldName=FieldParts[0];
    break;
    case 2:
    if (AllowRelation==false)
    throw new Exception("Relation specifiers not permitted in field list: '" + Fields[i] + "'.");
    Field.RelationName = FieldParts[0].Trim();
    Field.FieldName=FieldParts[1].Trim();
    break;
    default:
    throw new Exception("Invalid field definition: " + Fields[i] + "'.");
    }
    if (Field.FieldAlias==null)
    Field.FieldAlias = Field.FieldName;
    m_FieldInfo.Add (Field);
    }
    }

CreateJoinTable-Methode

Dieser Abschnitt enthält den Code für die CreateJoinTable -Methode.

Die Aufrufkonvention für die Methode CreateJoinTable ist:
dt = dsHelper.CreateJoinTable("TestTable", ds.Tables["Employees"],    "FirstName FName,LastName LName,DepartmentEmployee.DepartmentName Department");

Dieser Aufruf Beispiel erstellt eine neue DataTable mit TableName TestTable und drei Felder (FName LName und Abteilung). Diese drei Felder haben denselben Datentyp als der Vorname und Nachname Felder in der Tabelle Employees DepartmentName Feld in der übergeordneten Tabelle, die über das DepartmentEmployee DataRelation -Objekt zugegriffen wird.


Verwenden Sie folgende Syntax, um Felder in der Feldliste angeben:
[relationname.]fieldname[ alias], ...
Beachten Sie folgende Syntax:

  • Der Spaltenname und Datentyp -Eigenschaften sind die einzigen Eigenschaften, die an das Ziel DataTablekopiert werden.
  • Für Felder, die einen Ausdruck enthalten, wird das ausgewertete Ergebnis kopiert.
  • Sie können ein Feld im Ziel DataTable umbenennen, ein Aliasname angegeben.
  • Die Feldliste kann eine Teilmenge der Feldnamen enthalten, die in einer anderen Reihenfolge als der Reihenfolge in der Quelle DataTableaufgeführt sind. Wenn die Feldliste leer ist, wird eine Ausnahme ausgelöst.
  • DataRelation muss die übergeordneten Tabellen beziehen. Möchten Sie eine Tabelle erstellen, die die Felder der Kunden, Mitarbeiter und der Tabelle Orders, müssen Sie beispielsweise der Orders-Tabelle als Quelltabelle verwenden und Felder in den Tabellen Customers und die Mitarbeiter mit Geschäftsbeziehungen verweisen.
Fügen Sie zum Aufrufen der CreateJoinTable -Methode die folgende Methode der DataSetHelper -Klasse, die im Abschnitt "DataSetHelper-Shell-Klasse" erstellt:
public DataTable CreateJoinTable(string TableName, DataTable SourceTable, string FieldList){
/*
* Creates a table based on fields of another table and related parent tables
*
* FieldList syntax: [relationname.]fieldname[ alias][,[relationname.]fieldname[ alias]]...
*/
if (FieldList==null)
{
throw new ArgumentException("You must specify at least one field in the field list.");
//return CreateTable(TableName, SourceTable);
}
else
{
DataTable dt = new DataTable(TableName);
ParseFieldList(FieldList, true);
foreach(FieldInfo Field in m_FieldInfo)
{
if(Field.RelationName==null)
{
DataColumn dc = SourceTable.Columns[Field.FieldName];
dt.Columns.Add(dc.ColumnName, dc.DataType, dc.Expression);
}
else
{
DataColumn dc = SourceTable.ParentRelations[Field.RelationName].ParentTable.Columns[Field.FieldName];
dt.Columns.Add(dc.ColumnName, dc.DataType, dc.Expression);
}
}
if (ds!=null)
ds.Tables.Add(dt);
return dt;
}
}

InsertJoinInto-Methode

Dieser Abschnitt enthält Code für die InsertJoinInto -Methode. Die InsertJoinInto -Methode kopiert Datensätze, die sortiert und gefiltert aus der Quelltabelle und verknüpfte Tabellen in die Zieltabelle. Beim Aufruf von ParseFieldList können Sie Listen, die zuvor analysiert wurden, stehen diese Listen verarbeiten. Wenn die Feldliste leer ist, wird eine Ausnahme ausgelöst.


Die Aufrufkonvention für die Methode InsertJoinInto ist:
dsHelper.InsertJoinInto(ds.Tables["TestTable"], ds.Tables["Employees"],     "FirstName FName,LastName LName,DepartmentEmployee.DepartmentName Department", 
"EmployeeID<5", "BirthDate");

Aufruf-Beispiel kopiert Datensätze, die von Mitarbeitern DataTable und Feld DepartmentName verknüpfte DataTableTestTable DataTablegefiltert wird "EmployeeID < 5" und Geburtsdatum sortiert.

Hinweis: die Filter- und Sortierausdrücke gelten nur für die Quelltabelle und nicht auf alle verknüpften Tabellen.

Fügen Sie zum Aufrufen der InsertJoinInto -Methode die folgende Methode der DataSetHelper -Klasse, die im Abschnitt "DataSetHelper-Shell-Klasse" erstellt:
public void InsertJoinInto(DataTable DestTable, DataTable SourceTable,     string FieldList, string RowFilter, string Sort)
{
/*
* Copies the selected rows and columns from SourceTable and inserts them into DestTable
* FieldList has same format as CreatejoinTable
*/
if (FieldList==null)
{
throw new ArgumentException("You must specify at least one field in the field list.");
//InsertInto(DestTable, SourceTable, RowFilter, Sort);
}
else
{
ParseFieldList(FieldList, true);
DataRow[] Rows = SourceTable.Select(RowFilter, Sort);
foreach(DataRow SourceRow in Rows)
{
DataRow DestRow = DestTable.NewRow();
foreach(FieldInfo Field in m_FieldInfo)
{
if(Field.RelationName==null)
{
DestRow[Field.FieldName] = SourceRow[Field.FieldName];
}
else
{
DataRow ParentRow = SourceRow.GetParentRow(Field.RelationName);
DestRow[Field.FieldName] = ParentRow[Field.FieldName];
}
}
DestTable.Rows.Add(DestRow);
}
}
}

SelectJoinInto-Methode

Dieser Abschnitt enthält den Code für die SelectJoinInto -Methode. Diese Methode ist eine Kombination aus CreateJoinTable und InsertJoinInto -Methoden. Die SelectJoinInto -Methode erstellt eine neue DataTable anhand vorhandene DataTable -Objekte und Kopien, die in die neue Datentabellegefiltert und sortiert.


Die Aufrufkonvention für die Methode SelectJoinInto ist:
dt = dsHelper.SelectInto("TestTable", ds.Tables["Employees"],     "FirstName FName,LastName LName,DepartmentEmployee.DepartmentName Department", "EmployeeID<5", "BirthDate");

Dieser Funktionsaufruf erstellt eine DataTable namens TestTable mit drei Feldern. Diese drei Felder anhand der Vorname und Nachname Felder der Mitarbeiter DataTable und Feld DepartmentName DataTable , die durch DepartmentEmployee DataRelationverwiesen wird. Und dieses Beispiel Datensätze von Mitarbeitern DataTable TestTable DataTablekopiert, wodurch gefiltert wird "EmployeeID < 5" und Geburtsdatum sortiert.

Hinweis: die Filter- und Sortierausdrücke gelten nur für die Quelltabelle und nicht für verknüpfte Tabellen.

Fügen Sie zum Aufrufen der SelectJoinInto -Methode die folgende Methode der DataSetHelper -Klasse, die im Abschnitt "DataSetHelper-Shell-Klasse" erstellt:
public DataTable SelectJoinInto(string TableName, DataTable SourceTable, string FieldList, string RowFilter, string Sort){
/*
* Selects sorted, filtered values from one DataTable to another.
* Allows you to specify relationname.fieldname in the FieldList to include fields from
* a parent table. The Sort and Filter only apply to the base table and not to related tables.
*/
DataTable dt = CreateJoinTable(TableName, SourceTable, FieldList);
InsertJoinInto(dt, SourceTable, FieldList, RowFilter, Sort);
return dt;
}

Testen der Anwendung

  1. Speichern Sie und kompilieren Sie die DataSetHelper -Klasse, die in den vorherigen Abschnitten erstellt.
  2. Folgendermaßen Sie erstellen Sie ein neues Visual C# Windows-Anwendung
    1. Starten Sie Visual Studio .NET.
    2. Klicken Sie im Menü Datei auf neu und klicken Sie dann auf Projekt.
    3. Klicken Sie im Dialogfeld Neues Projekt klicken Sie unter Projekttypenauf Visual C#-Projekte , und klicken Sie unter Vorlagenauf Windows-Anwendung .
  3. Im Projektmappen-Explorer mit der rechten Maustaste der Projektmappe und dann auf Vorhandenes Projekt hinzufügen. Fügen Sie das DataSetHelper-Projekt hinzu.
  4. Klicken Sie im Menü Projekt auf Verweis hinzufügen.
  5. Klicken Sie im Dialogfeld Verweis hinzufügen klicken Sie auf die Registerkarte Projekte und fügen Sie einen Verweis auf das DataSetHelper-Projekt der Windows Form-Anwendung.
  6. Ziehen Sie im Formular-Designer drei Schaltflächen und ein DataGrid -Steuerelement aus der Toolbox in das Formular Benennen Sie die Schaltflächen, BtnCreateJoin, BtnInsertJoinIntound BtnSelectJoinInto. Behalten Sie den Standardnamen für das DataGrid -Steuerelement (dataGrid1).
  7. Fügen Sie im Formularcode die folgende Using -Anweisung am Anfang des Codefensters:
    using System.Data;
  8. Fügen Sie die folgenden Variablendeklarationen zu der Formulardefinition hinzu:
    DataSet ds; DataSetHelper.DataSetHelper dsHelper;
  9. Ereignis Form_Load den folgenden Code hinzufügen:
    ds = new DataSet();dsHelper = new DataSetHelper.DataSetHelper(ref ds);
    //Create source tables
    DataTable dt = new DataTable("Employees");
    dt.Columns.Add("EmployeeID",Type.GetType("System.Int32") );
    dt.Columns.Add("FirstName", Type.GetType("System.String"));
    dt.Columns.Add("LastName", Type.GetType("System.String"));
    dt.Columns.Add("BirthDate", Type.GetType("System.DateTime"));
    dt.Columns.Add("JobTitle", Type.GetType("System.String"));
    dt.Columns.Add("DepartmentID", Type.GetType("System.Int32"));
    dt.Rows.Add(new object[] {1, "Tommy", "Hill", new DateTime(1970, 12, 31), "Manager", 42});
    dt.Rows.Add(new object[] {2, "Brooke", "Sheals", new DateTime(1977, 12, 31), "Manager", 23});
    dt.Rows.Add(new object[] {3, "Bill", "Blast", new DateTime(1982, 5, 6), "Sales Clerk", 42});
    dt.Rows.Add(new object[] {1, "Kevin", "Kline", new DateTime(1978, 5, 13), "Sales Clerk", 42});
    dt.Rows.Add(new object[] {1, "Martha", "Seward", new DateTime(1976, 7, 4), "Sales Clerk", 23});
    dt.Rows.Add(new object[] {1, "Dora", "Smith", new DateTime(1985, 10, 22), "Trainee", 42});
    dt.Rows.Add(new object[] {1, "Elvis", "Pressman", new DateTime(1972, 11, 5), "Manager", 15});
    dt.Rows.Add(new object[] {1, "Johnny", "Cache", new DateTime(1984, 1, 23), "Sales Clerk", 15});
    dt.Rows.Add(new object[] {1, "Jean", "Hill", new DateTime(1979, 4, 14), "Sales Clerk", 42});
    dt.Rows.Add(new object[] {1, "Anna", "Smith", new DateTime(1985, 6, 26), "Trainee", 15});
    ds.Tables.Add(dt);

    dt = new DataTable("Departments");
    dt.Columns.Add("DepartmentID", Type.GetType("System.Int32"));
    dt.Columns.Add("DepartmentName", Type.GetType("System.String"));
    dt.Rows.Add(new object[] {15, "Men's Clothing"});
    dt.Rows.Add(new object[] {23, "Women's Clothing"});
    dt.Rows.Add(new object[] {42, "Children's Clothing"});
    ds.Tables.Add(dt);

    ds.Relations.Add("DepartmentEmployee", ds.Tables["Departments"].Columns["DepartmentID"],
    ds.Tables["Employees"].Columns["DepartmentID"]);

  10. Das BtnCreateJoin_Click -Ereignis den folgenden Code hinzufügen:
    dsHelper.CreateJoinTable("EmpDept",ds.Tables["Employees"],     "FirstName FName,LastName LName,BirthDate,DepartmentEmployee.DepartmentName Department");
    dataGrid1.SetDataBinding(ds, "EmpDept");

  11. Das BtnInsertJoinInto_Click -Ereignis den folgenden Code hinzufügen:
    dsHelper.InsertJoinInto(ds.Tables["EmpDept"], ds.Tables["Employees"],     "FirstName FName,LastName LName,BirthDate,DepartmentEmployee.DepartmentName Department",
    "JobTitle='Sales Clerk'", "DepartmentID");
    dataGrid1.SetDataBinding(ds, "EmpDept");

  12. Das BtnSelectJoinInto_Click -Ereignis den folgenden Code hinzufügen:
    dsHelper.SelectJoinInto("EmpDept2", ds.Tables["Employees"],    "FirstName,LastName,BirthDate BDate,DepartmentEmployee.DepartmentName Department", 
    "JobTitle='Manager'", "DepartmentID");
    dataGrid1.SetDataBinding(ds, "EmpDept2");

  13. Führen Sie die Anwendung, und klicken Sie dann auf die Schaltflächen. Beachten Sie, dass das DataGrid die Tabellen mit Daten aus dem Code aufgefüllt wird.

    Hinweis: Sie können nur BtnCreateJoin und BtnSelectJoinInto -Schaltflächen klicken Sie einmal auf. Wenn Sie eine dieser Schaltflächen nur einmal klicken, erhalten Sie eine Fehlermeldung, die versuchen, dieselbe Tabelle zweimal hinzuzufügen. Außerdem müssen Sie BtnCreateJoin zuerst auf BtnInsertJoinIntoklicken; Andernfalls wird das Ziel DataTable erstellt. Wenn Sie die BtnInsertJoinInto mehrere Male klicken, füllen Sie das DataGrid mit Duplikaten.

Erweiterung Ideen

  • Der Spaltenname und Datentyp -Eigenschaften sind die einzigen Eigenschaften, die an das Ziel DataTablekopiert werden. Erweitern Sie die CreateTable -Methode, um zusätzliche Eigenschaften wie die MaxLength -Eigenschaft kopieren oder neue Spalten erstellen.
  • Die Expression -Eigenschaft wird nicht kopiert. Stattdessen wird das ausgewertete Ergebnis kopiert. Daher müssen Sie keinen Felder hinzufügen, die durch den Ausdruck in die Zieltabelle verwiesen wird. Außerdem kann die Zielspalte in der Ergebnisliste als Spalten angezeigt, von denen diese Spalte andernfalls abhängt. Sie können die CreateTable -Methode, um den Ausdruck (InsertInto Spalte ignoriert Spalten mit einem Ausdruck) kopieren, Einschränkungen ist die in diesem Absatz genannten.
  • CreateTable, InsertIntound SelectInto -Methoden können die Funktionen CreateJoinTable, InsertJoinIntound SelectJoinInto -Methoden zusammengeführt werden. Weitere CreateTable, InsertIntound SelectInto -Methoden finden Sie im Artikel der Microsoft Knowledge Base:

    326009 so wird's gemacht: implementieren eine Hilfsklasse DataSet SELECT INTO in Visual C# .NET
    Möchten Sie nicht, diese Methoden zusammenzuführen, jedoch haben Sie beide Methoden in einer Klasse können Sie CreateJoinTable und InsertJoinInto -Methoden, eine leere Liste die Throw -Anweisungen, und indem Sie auskommentieren Aufrufe CreateTable behandeln und InsertInto -Methoden in den folgenden Codezeilen:
        if (FieldList==null)    {
    throw new ArgumentException("You must specify at least one field in the field list.");
    //return CreateTable(TableName, SourceTable);
    }

    - und -
        if (FieldList==null)    {
    throw new ArgumentException("You must specify at least one field in the field list.");
    //InsertInto(DestTable, SourceTable, RowFilter, Sort);
    }

Problembehandlung:

  • Der Feldname und die Aliasnamen der Feldliste müssen DataColumn Benennungskonventionen entsprechen. Der Parser kann die Namen, der Namen keinen Punkt (.) enthalten muss ein Komma (,) oder ein Leerzeichen ().
  • Wenn Sie mehr als einmal eine Schaltfläche klicken, wird dieselbe Tabelle zweimal DataSethinzugefügt, die zu einer Ausnahme führt. Um dieses Problem zu umgehen, können Sie Code Hinzufügen der Anwendung überprüfen, ob eine DataTable mit dem gleichen Namen ist bereits vorhanden. Alternativ können Sie die DataSetHelper -Klasse ohne einen Verweis auf ein DataSet erstellen und binden DataGrid.DataSource -Eigenschaft direkt an dt Variable statt mit der SetDataBinding -Methodenaufruf.
  • Wenn die Quelltabelle benutzerdefinierte Datentypen (eine Klasse) verwendet, müssen Sie die InsertJoinInto -Methode eine Tiefenkopie der Daten durchzuführen Code hinzufügen. Andernfalls wird nur ein Verweis kopiert.
Eigenschaften

Artikelnummer: 326080 – Letzte Überarbeitung: 16.01.2017 – Revision: 2

Feedback