Binden von Objekten als Datenquellen in .NET Framework-Anwendungen mit Visual Studio

Hinweis

Datasets und verwandte Klassen sind ältere .NET-Technologien aus den frühen 2000er Jahren, die es Anwendungen ermöglichen, mit Daten im Arbeitsspeicher zu arbeiten, während die Anwendungen von der Datenbank getrennt sind. Die Technologien sind besonders nützlich für Anwendungen, die es Benutzern ermöglichen, Daten zu ändern und die Änderungen wieder in der Datenbank zu speichern. Obwohl sich Datasets als sehr erfolgreiche Technologie erwiesen haben, empfehlen wir, dass neue .NET-Anwendungen Entity Framework Core verwenden. Entity Framework bietet eine natürlichere Möglichkeit, mit tabellarischen Daten als Objektmodelle zu arbeiten, und verfügt über eine einfachere Programmierschnittstelle.

Visual Studio bietet Entwurfszeittools für die Arbeit mit benutzerdefinierten Objekten als Datenquelle in Ihrer Anwendung. Wenn Sie Daten aus einer Datenbank in einem Objekt speichern möchten, das Sie an Benutzeroberflächen-Steuerelemente binden, empfiehlt es sich, Entity Framework zum Generieren der Klasse(n) zu verwenden. Entity Framework generiert automatisch alle Codebausteine für die Änderungsnachverfolgung, was bedeutet, dass alle Änderungen an den lokalen Objekten automatisch in der Datenbank gespeichert werden, wenn Sie AcceptChanges für das DbSet-Objekt aufrufen. Weitere Informationen finden Sie unter Dokumentation zu Entity Framework.

Tipp

Die Ansätze zur Objektbindung in diesem Artikel sollten nur dann in Betracht gezogen werden, wenn Ihre Anwendung bereits auf Datasets basiert. Sie können diese Ansätze auch verwenden, wenn Sie bereits mit Datasets vertraut sind und die zu verarbeitenden Daten tabellarisch und nicht zu komplex oder zu groß sind. Ein noch einfacheres Beispiel für das direkte Laden von Daten in Objekte mithilfe eines DataReader und das manuelle Aktualisieren der Benutzeroberfläche ohne Datenbindung finden Sie unter Erstellen einer einfachen Datenanwendung mithilfe von ADO.NET.

Objektanforderungen

Die einzige Anforderung für benutzerdefinierte Objekte für die Arbeit mit den Datenentwurfstools in Visual Studio besteht darin, dass das Objekt mindestens eine öffentliche Eigenschaft benötigt.

Im Allgemeinen erfordern benutzerdefinierte Objekte keine spezifischen Schnittstellen, Konstruktoren oder Attribute, die als Datenquelle für eine Anwendung fungieren. Wenn Sie das Objekt jedoch aus dem Fenster Datenquellen auf eine Entwurfsoberfläche ziehen möchten, um ein datengebundenes Steuerelement zu erstellen, und wenn das Objekt die ITypedList- oder IListSource-Schnittstelle implementiert, muss das Objekt über einen Standardkonstruktor verfügen. Andernfalls kann Visual Studio das Datenquellenobjekt nicht instanziieren und zeigt einen Fehler an, wenn Sie das Element auf die Entwurfsoberfläche ziehen.

Beispiele für die Verwendung von benutzerdefinierten Objekten als Datenquellen

Obwohl es unzählige Möglichkeiten gibt, Ihre Anwendungslogik beim Arbeiten mit Objekten als Datenquelle zu implementieren, gibt es für SQL-Datenbanken einige Standardvorgänge, die mithilfe der von Visual Studio generierten TableAdapter-Objekte vereinfacht werden können. Auf dieser Seite wird erläutert, wie diese Standardprozesse mithilfe von TableAdapters implementiert werden. Sie ist nicht als Leitfaden zum Erstellen von benutzerdefinierten Objekte gedacht. Beispielsweise führen Sie in der Regel die folgenden Standardvorgänge unabhängig von der spezifischen Implementierung Ihrer Objekte oder der Logik der Anwendung aus:

  • Laden von Daten in Objekte (in der Regel aus einer Datenbank)

  • Erstellen einer typisierten Sammlung von Objekten

  • Hinzufügen von Objekten zu und Entfernen von Objekten aus einer Sammlung

  • Anzeigen der Objektdaten für Benutzer in einem Formular

  • Ändern/Bearbeiten der Daten in einem Objekt

  • Erneutes Speichern von Daten aus Objekten in der Datenbank

Laden von Daten in Objekte

In diesem Beispiel laden Sie Daten mithilfe von TableAdapters in Ihre Objekte. TableAdapters werden standardmäßig mit zwei Methodentypen erstellt, die Daten aus einer Datenbank abrufen und Datentabellen auffüllen.

  • Die TableAdapter.Fill-Methode füllt eine vorhandene Datentabelle mit den zurückgegebenen Daten aus.

  • Die TableAdapter.GetData-Methode gibt eine neue Datentabelle zurück, die mit Daten aufgefüllt ist.

Die einfachste Möglichkeit zum Laden benutzerdefinierter Objekte mit Daten besteht darin, die TableAdapter.GetData-Methode aufzurufen, die Sammlung von Zeilen in der zurückgegebenen Datentabelle zu durchlaufen und jedes Objekt mit den Werten in jeder Zeile aufzufüllen. Sie können eine GetData-Methode erstellen, die eine ausgefüllte Datentabelle für jede Abfrage zurückgibt, die einem TableAdapter hinzugefügt wurde.

Hinweis

Visual Studio benennt die TableAdapter-Abfragen standardmäßig Fill und GetData. Sie können diese Namen jedoch in einen beliebigen gültigen Methodennamen ändern.

Das folgende Beispiel zeigt, wie die Zeilen in einer Datentabelle durchlaufen und ein Objekt mit Daten aufgefüllt wird:

private void LoadCustomers()
{
    NorthwindDataSet.CustomersDataTable customerData = 
        customersTableAdapter1.GetTop5Customers();
    
    foreach (NorthwindDataSet.CustomersRow customerRow in customerData)
    {
        Customer currentCustomer = new Customer();
        currentCustomer.CustomerID = customerRow.CustomerID;
        currentCustomer.CompanyName = customerRow.CompanyName;

        if (customerRow.IsAddressNull() == false)
        {
            currentCustomer.Address = customerRow.Address;
        }

        if (customerRow.IsCityNull() == false)
        {
            currentCustomer.City = customerRow.City;
        }

        if (customerRow.IsContactNameNull() == false)
        {
            currentCustomer.ContactName = customerRow.ContactName;
        }

        if (customerRow.IsContactTitleNull() == false)
        {
            currentCustomer.ContactTitle = customerRow.ContactTitle;
        }

        if (customerRow.IsCountryNull() == false)
        {
            currentCustomer.Country = customerRow.Country;
        }

        if (customerRow.IsFaxNull() == false)
        {
            currentCustomer.Fax = customerRow.Fax;
        }

        if (customerRow.IsPhoneNull() == false)
        {
            currentCustomer.Phone = customerRow.Phone;
        }

        if (customerRow.IsPostalCodeNull() == false)
        {
            currentCustomer.PostalCode = customerRow.PostalCode;
        }

        if (customerRow.IsRegionNull() == false)
        {
            currentCustomer.Region = customerRow.Region;
        }

        LoadOrders(currentCustomer);
        customerBindingSource.Add(currentCustomer);
    }
}

Erstellen einer typisierten Sammlung von Objekten

Sie können Sammlungsklassen für Ihre Objekte erstellen oder die typisierten Sammlungen verwenden, die automatisch von der BindingSource-Komponente bereitgestellt werden.

Wenn Sie eine benutzerdefinierte Sammlungsklasse für Objekte erstellen, wird empfohlen, dass Sie von BindingList<T> erben. Diese generische Klasse bietet Funktionen zum Verwalten Ihrer Sammlung sowie die Möglichkeit, Ereignisse auszulösen, die Benachrichtigungen an die Datenbindungsinfrastruktur in Windows Forms senden.

Die automatisch generierte Sammlung in der BindingSource verwendet eine BindingList<T> für die typisierte Sammlung. Wenn Ihre Anwendung keine zusätzliche Funktionalität erfordert, können Sie Ihre Sammlung innerhalb der BindingSource verwalten. Weitere Informationen finden Sie auf der Seite zur List-Eigenschaft der BindingSource-Klasse.

Hinweis

Wenn Ihre Sammlung Funktionen erfordert, die nicht von der Basisimplementierung der BindingList<T> bereitgestellt werden, sollten Sie eine benutzerdefinierte Sammlung erstellen, damit Sie die Klasse nach Bedarf hinzufügen können.

Der folgende Code zeigt, wie Sie die Klasse für eine stark typisierte Sammlung von Order-Objekten erstellen:

/// <summary>
/// A collection of Orders
/// </summary>
public class Orders: System.ComponentModel.BindingList<Order>
{
    // Add any additional functionality required by your collection.
}

Hinzufügen von Objekten zu einer Sammlung

Sie fügen einer Sammlung Objekte hinzu, indem Sie die Add-Methode der benutzerdefinierten Sammlungsklasse oder der BindingSourceaufrufen.

Hinweis

Die Add-Methode wird automatisch für Ihre benutzerdefinierte Sammlung bereitgestellt, wenn Sie von BindingList<T> erben.

Der folgende Code zeigt, wie Sie der typisierten Sammlung in einer BindingSource Objekte hinzufügen:

Customer currentCustomer = new Customer();
customerBindingSource.Add(currentCustomer);

Der folgende Code zeigt, wie Sie einer typisierten Sammlung, die von BindingList<T> erbt, Objekte hinzufügen:

Hinweis

In diesem Beispiel ist die Orders-Sammlung eine Eigenschaft des Customer-Objekts.

Order currentOrder = new Order();
currentCustomer.Orders.Add(currentOrder);

Entfernen von Objekten aus einer Sammlung

Sie entfernen Objekte aus einer Sammlung, indem Sie die Remove- oder RemoveAt-Methode der benutzerdefinierten Sammlungsklasse oder der BindingSource aufrufen.

Hinweis

Die Methoden Remove und RemoveAt werden automatisch für Ihre benutzerdefinierte Sammlung bereitgestellt, wenn Sie von BindingList<T>erben.

Der folgende Code zeigt, wie Objekte aus der typisierten Sammlung in einer BindingSource mit der RemoveAt-Methode gefunden und entfernt werden:

int customerIndex = customerBindingSource.Find("CustomerID", "ALFKI");
customerBindingSource.RemoveAt(customerIndex);

Anzeigen von Objektdaten für Benutzer

Um die Daten in Objekten für Benutzer anzuzeigen, erstellen Sie eine Objektdatenquelle mithilfe des Assistenten Datenquellenkonfiguration, und ziehen Sie dann das gesamte Objekt oder einzelne Eigenschaften aus dem Fenster Datenquellen auf das Formular.

Ändern der Daten in Objekten

Wenn Sie Daten in benutzerdefinierten Objekten bearbeiten möchten, die an Windows Forms-Steuerelemente gebunden sind, bearbeiten Sie einfach die Daten im gebundenen Steuerelement (oder direkt in den Eigenschaften des Objekts). Die Datenbindungsarchitektur aktualisiert die Daten im Objekt.

Wenn Ihre Anwendung die Nachverfolgung von Änderungen und das Zurücksetzen vorgeschlagener Änderungen auf ihre ursprünglichen Werte erfordert, müssen Sie diese Funktionalität in Ihrem Objektmodell implementieren. Beispiele dafür, wie Datentabellen vorgeschlagene Änderungen nachverfolgen, finden Sie unter DataRowState, HasChanges und GetChanges.

Erneutes Speichern von Daten aus Objekten in der Datenbank

Speichern Sie Daten erneut in der Datenbank, indem Sie die Werte aus Ihrem Objekt an die DBDirect-Methoden des TableAdapter übergeben.

Visual Studio erstellt DBDirect-Methoden, die direkt für die Datenbank ausgeführt werden können. Diese Methoden erfordern keine DataSet- oder DataTable-Objekte.

TableAdapter-DBDirect-Methode BESCHREIBUNG
TableAdapter.Insert Fügt einer Datenbank neue Datensätze hinzu, sodass Sie einzelne Spaltenwerte als Methodenparameter übergeben können
TableAdapter.Update Aktualisiert vorhandene Datensätze in einer Datenbank. Die Update-Methode verwendet ursprüngliche und neue Spaltenwerte als Methodenparameter. Die ursprünglichen Werte werden verwendet, um den ursprünglichen Datensatz zu finden, und die neuen Werte werden verwendet, um diesen Datensatz zu aktualisieren.

Die TableAdapter.Update-Methode wird auch verwendet, um Änderungen in einem Dataset mit der Datenbank abzugleichen, indem DataSet, DataTable, DataRow oder Array von DataRows als Methodenparameter verwendet wird.
TableAdapter.Delete Löscht vorhandene Datensätze aus der Datenbank auf Grundlage der ursprünglichen Spaltenwerte, die als Methodenparameter übergeben werden

Um Daten aus einer Sammlung von Objekten zu speichern, durchlaufen Sie die Sammlung von Objekten (z. B. mithilfe einer For-Next-Schleife). Senden Sie die Werte für jedes Objekt mithilfe der DBDirect-Methoden von TableAdapter an die Datenbank.

Das folgende Beispiel zeigt, wie Sie die TableAdapter.Insert-DBDirect-Methode verwenden, um einen neuen Kunden direkt in die Datenbank einzufügen:

private void AddNewCustomers(Customer currentCustomer)
{
    customersTableAdapter.Insert( 
        currentCustomer.CustomerID, 
        currentCustomer.CompanyName, 
        currentCustomer.ContactName, 
        currentCustomer.ContactTitle, 
        currentCustomer.Address, 
        currentCustomer.City, 
        currentCustomer.Region, 
        currentCustomer.PostalCode, 
        currentCustomer.Country, 
        currentCustomer.Phone, 
        currentCustomer.Fax);
}