Share via


Arbeiten mit berechneten Spalten (C#)

von Scott Mitchell

PDF herunterladen

Beim Erstellen einer Datenbanktabelle können Sie mit Microsoft SQL Server eine berechnete Spalte definieren, deren Wert aus einem Ausdruck berechnet wird, der normalerweise auf andere Werte im gleichen Datenbankdatensatz verweist. Solche Werte sind in der Datenbank schreibgeschützt, was bei der Arbeit mit TableAdapters besondere Überlegungen erfordert. In diesem Tutorial erfahren Sie, wie Sie die Herausforderungen bewältigen, die durch berechnete Spalten gestellt werden.

Einführung

Microsoft SQL Server ermöglicht berechnete Spalten, bei denen es sich um Spalten handelt, deren Werte aus einem Ausdruck berechnet werden, der normalerweise auf die Werte aus anderen Spalten in derselben Tabelle verweist. Als Beispiel kann ein Zeitverfolgungsdatenmodell eine Tabelle mit dem Namen ServiceLog mit Spalten enthalten, die ServicePerformedu. a. , EmployeeID, Rateund Durationenthalten. Während der fällige Betrag pro Dienstelement (wobei die Rate multipliziert mit der Dauer) über eine Webseite oder eine andere programmgesteuerte Schnittstelle berechnet werden kann, kann es praktisch sein, eine Spalte mit dem Namen AmountDue in die Tabelle aufzunehmen, die ServiceLog diese Informationen gemeldet hat. Diese Spalte kann als normale Spalte erstellt werden, muss jedoch aktualisiert werden, wenn sich die Werte oder Duration der Rate Spalten ändern. Ein besserer Ansatz wäre, die AmountDue Spalte mithilfe des Ausdrucks Rate * Durationzu einer berechneten Spalte zu machen. Dies würde dazu führen, dass SQL Server automatisch den AmountDue Spaltenwert berechnet, wenn in einer Abfrage darauf verwiesen wird.

Da der Wert einer berechneten Spalte durch einen Ausdruck bestimmt wird, sind diese Spalten schreibgeschützt und können daher keine Werte in INSERT oder UPDATE -Anweisungen zugewiesen haben. Wenn berechnete Spalten jedoch Teil der Standard Abfrage für einen TableAdapter sind, der Ad-hoc-SQL-Anweisungen verwendet, werden sie automatisch in die automatisch generierten INSERT anweisungen und UPDATE eingeschlossen. Folglich müssen die TableAdapter-Abfragen INSERT und UPDATE -Eigenschaften und InsertCommand - UpdateCommand Eigenschaften aktualisiert werden, um Verweise auf alle berechneten Spalten zu entfernen.

Eine Herausforderung bei der Verwendung von berechneten Spalten mit einem TableAdapter, der Ad-hoc-SQL-Anweisungen verwendet, besteht darin, dass die TableAdapter-Abfragen INSERT und UPDATE Abfragen automatisch generiert werden, sobald der TableAdapter-Konfigurations-Assistent abgeschlossen ist. Daher werden die berechneten Spalten, die INSERT manuell aus dem entfernt wurden, und UPDATE Abfragen wieder angezeigt, wenn der Assistent erneut ausgeführt wird. Obwohl TableAdapters, die gespeicherte Prozeduren verwenden, nicht an dieser Brüchigkeit leiden, haben sie ihre eigenen Macken, die wir in Schritt 3 behandeln werden.

In diesem Tutorial fügen wir der Tabelle in der Suppliers Northwind-Datenbank eine berechnete Spalte hinzu und erstellen dann einen entsprechenden TableAdapter, um mit dieser Tabelle und der zugehörigen berechneten Spalte zu arbeiten. Unser TableAdapter verwendet gespeicherte Prozeduren anstelle von Ad-hoc-SQL-Anweisungen, damit unsere Anpassungen nicht verloren gehen, wenn der TableAdapter-Konfigurations-Assistent verwendet wird.

Los geht's!

Schritt 1: Hinzufügen einer berechneten Spalte zurSuppliersTabelle

Die Northwind-Datenbank verfügt über keine berechneten Spalten, daher müssen sie selbst hinzugefügt werden. In diesem Tutorial fügen Sie der Tabelle eine berechnete Spalte mit dem Namen FullContactName hinzu, die Suppliers den Namen des Kontakts, den Titel und das Unternehmen, für das er arbeitet, im folgenden Format zurückgibt: ContactName (ContactTitle, CompanyName). Diese berechnete Spalte kann in Berichten verwendet werden, wenn Informationen zu Lieferanten angezeigt werden.

Öffnen Sie zunächst die Suppliers Tabellendefinition, indem Sie mit der rechten Maustaste auf die Suppliers Tabelle im Explorer Server klicken und im Kontextmenü Tabellendefinition öffnen auswählen. Dadurch werden die Spalten der Tabelle und ihre Eigenschaften angezeigt, z. B. ihr Datentyp, ob sie s zulassen NULL usw. Um eine berechnete Spalte hinzuzufügen, geben Sie zunächst den Namen der Spalte in die Tabellendefinition ein. Geben Sie als Nächstes seinen Ausdruck in das Textfeld (Formel) im Abschnitt Berechnete Spaltenspezifikation im Eigenschaftenfenster Spalte ein (siehe Abbildung 1). Benennen Sie die berechnete Spalte FullContactName , und verwenden Sie den folgenden Ausdruck:

ContactName + ' (' + CASE WHEN ContactTitle IS NOT NULL THEN 
    ContactTitle + ', ' ELSE '' END + CompanyName + ')'

Beachten Sie, dass Zeichenfolgen mit dem + Operator in SQL verkettet werden können. Die CASE Anweisung kann wie eine Bedingung in einer herkömmlichen Programmiersprache verwendet werden. Im obigen Ausdruck kann die CASE Anweisung als gelesen werden: Wenn ContactTitle nicht NULL , geben Sie den ContactTitle Wert mit einem Komma verkettet aus, andernfalls geben Sie nichts aus. Weitere Informationen zur Nützlichkeit der CASE Anweisung finden Sie unter SQL-AnweisungenCASE.

Hinweis

Anstatt hier eine CASE Anweisung zu verwenden, hätten wir alternativ verwenden ISNULL(ContactTitle, '')können. ISNULL(checkExpression, replacementValue) gibt checkExpression zurück, wenn es nicht NULL ist, andernfalls wird replacementValue zurückgegeben. Während entweder ISNULL oder CASE in diesem instance funktioniert, gibt es komplexere Szenarien, in denen die Flexibilität der CASE Anweisung nicht mit ISNULLübereinstimmen kann.

Nachdem Sie diese berechnete Spalte hinzugefügt haben, sollte Ihr Bildschirm wie der Screenshot in Abbildung 1 aussehen.

Hinzufügen einer berechneten Spalte mit dem Namen FullContactName zur Tabelle

Abbildung 1: Hinzufügen einer berechneten Spalte namens FullContactName zur Suppliers Tabelle (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Nachdem Sie die berechnete Spalte benannt und ihren Ausdruck eingegeben haben, speichern Sie die Änderungen an der Tabelle, indem Sie auf der Symbolleiste auf das Symbol Speichern klicken, STRG+S drücken oder zum Menü Datei wechseln und Speichern Suppliersauswählen.

Das Speichern der Tabelle sollte die Server-Explorer aktualisieren, einschließlich der gerade hinzugefügten Spalte in der Spaltenliste der Suppliers Tabelle. Darüber hinaus wird der in das Textfeld (Formel) eingegebene Ausdruck automatisch an einen entsprechenden Ausdruck angepasst, der unnötige Leerzeichen entfernt, Spaltennamen mit Klammern ([]) umgibt und Klammern enthält, um die Reihenfolge der Vorgänge expliziter anzuzeigen:

(((([ContactName]+' (')+case when [ContactTitle] IS NOT NULL 
    then [ContactTitle]+', ' else '' end)+[CompanyName])+')')

Weitere Informationen zu berechneten Spalten in Microsoft SQL Server finden Sie in der technischen Dokumentation. Sehen Sie sich auch die Vorgehensweise: Angeben von berechneten Spalten an, um eine schrittweise exemplarische Vorgehensweise zum Erstellen von berechneten Spalten zu finden.

Hinweis

Standardmäßig werden berechnete Spalten nicht physisch in der Tabelle gespeichert, sondern jedes Mal neu berechnet, wenn in einer Abfrage darauf verwiesen wird. Durch Aktivieren des Kontrollkästchens Persisted können Sie jedoch SQL Server anweisen, die berechnete Spalte in der Tabelle physisch zu speichern. Dadurch kann ein Index für die berechnete Spalte erstellt werden, wodurch die Leistung von Abfragen verbessert werden kann, die den berechneten Spaltenwert in ihren WHERE Klauseln verwenden. Weitere Informationen finden Sie unter Erstellen von Indizes für berechnete Spalten .

Schritt 2: Anzeigen der Werte der berechneten Spalte

Bevor wir mit der Arbeit an der Datenzugriffsebene beginnen, nehmen wir uns eine Minute Zeit, um die FullContactName Werte anzuzeigen. Klicken Sie im Explorer Server mit der rechten Maustaste auf den Suppliers Tabellennamen, und wählen Sie im Kontextmenü Neue Abfrage aus. Dadurch wird ein Abfragefenster geöffnet, in dem wir aufgefordert werden, auszuwählen, welche Tabellen in die Abfrage eingeschlossen werden sollen. Fügen Sie die Tabelle hinzu Suppliers , und klicken Sie auf Schließen. Überprüfen Sie als Nächstes die CompanyNameSpalten , ContactName, ContactTitleund FullContactName aus der Tabelle Suppliers. Klicken Sie abschließend auf das rote Ausrufezeichensymbol in der Symbolleiste, um die Abfrage auszuführen und die Ergebnisse anzuzeigen.

Wie Abbildung 2 zeigt, enthalten FullContactNamedie Ergebnisse , die die CompanyNameSpalten , ContactNameund ContactTitle im Format ldquo;ContactName (ContactTitle, CompanyName) auflistet.

FullContactName verwendet das Format ContactName (ContactTitle, CompanyName)

Abbildung 2: Verwendet FullContactName das Format ContactName (ContactTitle, CompanyName) (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Schritt 3: Hinzufügen von zurSuppliersTableAdapterDatenzugriffsebene

Um mit den Lieferanteninformationen in unserer Anwendung arbeiten zu können, müssen wir zuerst einen TableAdapter und eine DataTable in unserer DAL erstellen. Im Idealfall wird dies mithilfe der gleichen einfachen Schritte erreicht, die in früheren Tutorials untersucht wurden. Die Arbeit mit berechneten Spalten führt jedoch zu einigen Falten, die diskussionswürdig sind.

Wenn Sie einen TableAdapter verwenden, der Ad-hoc-SQL-Anweisungen verwendet, können Sie die berechnete Spalte einfach über den TableAdapter-Konfigurations-Assistenten in die Standard abfrage von TableAdapter einschließen. Dadurch werden jedoch automatisch Und-Anweisungen UPDATE generiertINSERT, die die berechnete Spalte enthalten. Wenn Sie versuchen, eine dieser Methoden auszuführen, wird eine SqlException mit der Meldung Die Spalte Spaltenname kann nicht geändert werden, da es sich entweder um eine berechnete Spalte handelt oder das Ergebnis eines UNION-Operators ist. Während die INSERT -Anweisung und UPDATE manuell über die TableAdapter-Eigenschaften InsertCommand und UpdateCommand -Eigenschaften angepasst werden kann, gehen diese Anpassungen verloren, wenn der TableAdapter-Konfigurations-Assistent erneut ausgeführt wird.

Aufgrund der Sprödigkeit von TableAdapters, die Ad-hoc-SQL-Anweisungen verwenden, wird empfohlen, gespeicherte Prozeduren beim Arbeiten mit berechneten Spalten zu verwenden. Wenn Sie vorhandene gespeicherte Prozeduren verwenden, konfigurieren Sie einfach den TableAdapter, wie im Tutorial Using Existing Stored Procedures for the Typed DataSet s TableAdapters erläutert. Wenn Der TableAdapter-Assistent die gespeicherten Prozeduren für Sie erstellt hat, ist es jedoch wichtig, zunächst alle berechneten Spalten aus der Standard Abfrage wegzulassen. Wenn Sie eine berechnete Spalte in die Standard-Abfrage einschließen, informiert Sie der TableAdapter-Konfigurations-Assistent nach Abschluss, dass die entsprechenden gespeicherten Prozeduren nicht erstellt werden können. Kurz gesagt, wir müssen zunächst den TableAdapter mithilfe einer berechneten spaltenfreien Standard Abfrage konfigurieren und dann die entsprechende gespeicherte Prozedur und die TableAdapter s SelectCommand manuell aktualisieren, um die berechnete Spalte einzuschließen. Dieser Ansatz ähnelt dem ansatz, der im Tutorial Aktualisieren des TableAdapter to UseJOINs verwendet wird.

Für dieses Tutorial fügen Sie einen neuen TableAdapter hinzu, und lassen Sie ihn automatisch die gespeicherten Prozeduren für uns erstellen. Daher müssen wir die berechnete Spalte zunächst aus der FullContactName Standard Abfrage weglassen.

Öffnen Sie zunächst das NorthwindWithSprocs DataSet im ~/App_Code/DAL Ordner. Klicken Sie mit der rechten Maustaste in den Designer, und wählen Sie im Kontextmenü einen neuen TableAdapter aus. Dadurch wird der TableAdapter-Konfigurations-Assistent gestartet. Geben Sie die Datenbank an, in der Daten von (NORTHWNDConnectionString von Web.config) abfragt werden sollen, und klicken Sie auf Weiter. Da wir noch keine gespeicherten Prozeduren zum Abfragen oder Ändern der Suppliers Tabelle erstellt haben, wählen Sie die Option Neue gespeicherte Prozeduren erstellen aus, damit der Assistent sie für uns erstellt, und klicken Sie auf Weiter.

Wählen Sie die Option Neue gespeicherte Prozeduren erstellen aus.

Abbildung 3: Wählen Sie die Option Neue gespeicherte Prozeduren erstellen aus (Klicken Sie, um das Bild in voller Größe anzuzeigen)

Im folgenden Schritt werden wir zur Standard Abfrage aufgefordert. Geben Sie die folgende Abfrage ein, die die SupplierIDSpalten , CompanyName, und ContactNameContactTitle für jeden Lieferanten zurückgibt. Beachten Sie, dass diese Abfrage die berechnete Spalte (FullContactName) absichtlich weglässt. Wir aktualisieren die entsprechende gespeicherte Prozedur so, dass diese Spalte in Schritt 4 eingeschlossen wird.

SELECT SupplierID, CompanyName, ContactName, ContactTitle
FROM Suppliers

Nachdem Sie die Standard Abfrage eingegeben und auf Weiter geklickt haben, können wir mit dem Assistenten die vier gespeicherten Prozeduren benennen, die er generiert. Nennen Sie diese gespeicherten Prozeduren Suppliers_Select, Suppliers_Insert, Suppliers_Updateund Suppliers_Delete, wie Abbildung 4 veranschaulicht.

Anpassen der Namen der automatisch generierten gespeicherten Prozeduren

Abbildung 4: Anpassen der Namen der automatisch generierten gespeicherten Prozeduren (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Im nächsten Assistentenschritt können wir die TableAdapter-Methoden benennen und die Muster angeben, die für den Zugriff auf und die Aktualisierung von Daten verwendet werden. Lassen Sie alle drei Kontrollkästchen aktiviert, benennen Sie die GetData Methode jedoch in um GetSuppliers. Klicken Sie auf Fertig stellen, um den Assistenten abzuschließen.

Benennen Sie die GetData-Methode in GetSuppliers um.

Abbildung 5: Umbenennen der GetData Methode in GetSuppliers (Klicken Sie hier, um das bild in voller Größe anzuzeigen)

Wenn Sie auf Fertig stellen klicken, erstellt der Assistent die vier gespeicherten Prozeduren und fügt dem typisierten DataSet den TableAdapter und die entsprechende DataTable hinzu.

Schritt 4: Einschließen der berechneten Spalte in die TableAdapter-Hauptabfrage

Wir müssen nun die in Schritt 3 erstellten Tabellenadapter und DataTable aktualisieren, um die FullContactName berechnete Spalte einzuschließen. Dies umfasst zwei Schritte:

  1. Aktualisieren der Suppliers_Select gespeicherten Prozedur, um die FullContactName berechnete Spalte zurückzugeben, und
  2. Aktualisieren der DataTable, um eine entsprechende FullContactName Spalte einzuschließen.

Navigieren Sie zunächst zum server-Explorer, und führen Sie einen Drilldown in den Ordner Gespeicherte Prozeduren durch. Öffnen Sie die Suppliers_Select gespeicherte Prozedur, und aktualisieren Sie die SELECT Abfrage, um die FullContactName berechnete Spalte einzuschließen:

SELECT SupplierID, CompanyName, ContactName, ContactTitle, FullContactName
FROM Suppliers

Speichern Sie die Änderungen an der gespeicherten Prozedur, indem Sie auf der Symbolleiste auf das Symbol Speichern klicken, STRG+S drücken oder im Menü Datei die Option Speichern Suppliers_Select auswählen.

Kehren Sie als Nächstes zum DataSet-Designer zurück, klicken Sie mit der rechten Maustaste auf , SuppliersTableAdapterund wählen Sie im Kontextmenü Konfigurieren aus. Beachten Sie, dass die Suppliers_Select Spalte jetzt die Spalte in der FullContactName Datenspaltenauflistung enthält.

Führen Sie den Konfigurations-Assistenten für TableAdapter aus, um die DataTable-Spalten zu aktualisieren.

Abbildung 6: Ausführen des Konfigurations-Assistenten für TableAdapter zum Aktualisieren der DataTable-Spalten (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Klicken Sie auf Fertig stellen, um den Assistenten abzuschließen. Dadurch wird automatisch eine entsprechende Spalte hinzugefügt SuppliersDataTable. Der TableAdapter-Assistent ist intelligent genug, um zu erkennen, dass die FullContactName Spalte eine berechnete Spalte ist und daher schreibgeschützt ist. Folglich wird die -Eigenschaft der Spalte ReadOnly auf truefestgelegt. Um dies zu überprüfen, wählen Sie die Spalte aus der SuppliersDataTable aus, und wechseln Sie dann zum Eigenschaftenfenster (siehe Abbildung 7). Beachten Sie, dass die FullContactName Spalteneigenschaften und DataTypeMaxLength -eigenschaften ebenfalls entsprechend festgelegt sind.

Die FullContactName-Spalte ist als schreibgeschützt gekennzeichnet.

Abbildung 7: Die FullContactName Spalte ist als Read-Only markiert (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Schritt 5: Hinzufügen einerGetSupplierBySupplierIDMethode zum TableAdapter

In diesem Tutorial erstellen wir eine ASP.NET Seite, auf der die Lieferanten in einem aktualisierbaren Raster angezeigt werden. In früheren Tutorials haben wir einen einzelnen Datensatz aus der Geschäftslogikebene aktualisiert, indem wir diesen bestimmten Datensatz aus der DAL als stark typisierte DataTable abrufen, dessen Eigenschaften aktualisiert und dann die aktualisierte DataTable zurück an die DAL senden, um die Änderungen an die Datenbank zu übertragen. Um diesen ersten Schritt zu erreichen – abrufen des Datensatzes, der aus dem DAL aktualisiert wird – müssen wir zunächst eine GetSupplierBySupplierID(supplierID) -Methode zur DAL hinzufügen.

Klicken Sie im DataSet-Entwurf mit der rechten Maustaste auf die SuppliersTableAdapter , und wählen Sie im Kontextmenü die Option Abfrage hinzufügen aus. Lassen Sie wie in Schritt 3 den Assistenten eine neue gespeicherte Prozedur generieren, indem Sie die Option Neue gespeicherte Prozedur erstellen auswählen (einen Screenshot dieses Assistentenschritts finden Sie zurück zu Abbildung 3). Da diese Methode einen Datensatz mit mehreren Spalten zurückgibt, geben Sie an, dass eine SQL-Abfrage verwendet werden soll, bei der es sich um eine SELECT-Abfrage handelt, die Zeilen zurückgibt, und klicken Sie auf Weiter.

Wählen Sie die OPTION SELECT aus, die Zeilen zurückgibt.

Abbildung 8: Auswählen der Option SELECT, die Zeilen zurückgibt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Im folgenden Schritt werden wir aufgefordert, die Abfrage für diese Methode zu verwenden. Geben Sie Folgendes ein, wodurch die gleichen Datenfelder wie die Standard Abfrage, aber für einen bestimmten Lieferanten zurückgegeben werden.

SELECT SupplierID, CompanyName, ContactName, ContactTitle, FullContactName
FROM Suppliers
WHERE SupplierID = @SupplierID

Auf dem nächsten Bildschirm werden wir aufgefordert, die gespeicherte Prozedur zu benennen, die automatisch generiert wird. Benennen Sie diese gespeicherte Prozedur, Suppliers_SelectBySupplierID und klicken Sie auf Weiter.

Benennen Sie die gespeicherte Prozedur Suppliers_SelectBySupplierID.

Abbildung 9: Benennen der gespeicherten Prozedur Suppliers_SelectBySupplierID (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Schließlich fordert der Assistent uns zur Eingabe der Datenzugriffsmuster und Methodennamen auf, die für den TableAdapter verwendet werden sollen. Lassen Sie beide Kontrollkästchen aktiviert, benennen Sie jedoch die FillBy Methoden und GetDataBy in bzwGetSupplierBySupplierID. umFillBySupplierID.

Nennen Sie die TableAdapter-Methoden FillBySupplierID und GetSupplierBySupplierID.

Abbildung 10: Benennen Sie die TableAdapter-Methoden FillBySupplierID und GetSupplierBySupplierID (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Klicken Sie auf Fertig stellen, um den Assistenten abzuschließen.

Schritt 6: Erstellen der Geschäftslogikebene

Bevor wir eine ASP.NET Seite erstellen, die die in Schritt 1 erstellte berechnete Spalte verwendet, müssen wir zunächst die entsprechenden Methoden in der BLL hinzufügen. Auf der Seite ASP.NET, die wir in Schritt 7 erstellen, können Benutzer Lieferanten anzeigen und bearbeiten. Daher benötigen wir unsere BLL, um mindestens eine Methode bereitzustellen, um alle Lieferanten und einen anderen zu erhalten, um einen bestimmten Lieferanten zu aktualisieren.

Erstellen Sie eine neue Klassendatei namens SuppliersBLLWithSprocs im ~/App_Code/BLL Ordner, und fügen Sie den folgenden Code hinzu:

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using NorthwindWithSprocsTableAdapters;
[System.ComponentModel.DataObject]
public class SuppliersBLLWithSprocs
{
    private SuppliersTableAdapter _suppliersAdapter = null;
    protected SuppliersTableAdapter Adapter
    {
        get
        {
            if (_suppliersAdapter == null)
                _suppliersAdapter = new SuppliersTableAdapter();
            return _suppliersAdapter;
        }
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Select, true)]
    public NorthwindWithSprocs.SuppliersDataTable GetSuppliers()
    {
        return Adapter.GetSuppliers();
    }
    [System.ComponentModel.DataObjectMethodAttribute
        (System.ComponentModel.DataObjectMethodType.Update, true)]
    public bool UpdateSupplier(string companyName, string contactName, 
        string contactTitle, int supplierID)
    {
        NorthwindWithSprocs.SuppliersDataTable suppliers = 
            Adapter.GetSupplierBySupplierID(supplierID);
        if (suppliers.Count == 0)
            // no matching record found, return false
            return false;
        NorthwindWithSprocs.SuppliersRow supplier = suppliers[0];
        supplier.CompanyName = companyName;
        if (contactName == null) 
            supplier.SetContactNameNull(); 
        else 
            supplier.ContactName = contactName;
        if (contactTitle == null) 
            supplier.SetContactTitleNull(); 
        else 
            supplier.ContactTitle = contactTitle;
        // Update the product record
        int rowsAffected = Adapter.Update(supplier);
        // Return true if precisely one row was updated, otherwise false
        return rowsAffected == 1;
    }
}

Hat wie die anderen BLL-Klassen eine protectedAdapter -Eigenschaft, SuppliersBLLWithSprocs die eine instance der SuppliersTableAdapter -Klasse zusammen mit zwei public Methoden zurückgibt: GetSuppliers und UpdateSupplier. Die GetSuppliers -Methode ruft auf und gibt die SuppliersDataTable zurück, die von der entsprechenden GetSupplier Methode in der Datenzugriffsebene zurückgegeben wird. Die UpdateSupplier -Methode ruft Informationen über den jeweiligen Lieferanten ab, der aktualisiert wird, über einen Aufruf der DAL-Methode GetSupplierBySupplierID(supplierID) . Anschließend werden die CategoryNameEigenschaften , ContactNameund ContactTitle aktualisiert und diese Änderungen in die Datenbank übernommen, indem die Data Access Layer s-Methode Update aufgerufen und das geänderte SuppliersRow Objekt übergeben wird.

Hinweis

Mit Ausnahme von SupplierID und CompanyNamelassen alle Spalten in der Tabelle Suppliers Werte zu NULL . Wenn die übergebenen contactName Parameter oder contactTitle Parameter vorliegennull, müssen wir daher die entsprechenden ContactName Eigenschaften und ContactTitle mit den SetContactNameNull Methoden und SetContactTitleNull auf einen NULL Datenbankwert festlegen.

Schritt 7: Arbeiten mit der berechneten Spalte auf der Präsentationsebene

Nachdem die berechnete Spalte der Suppliers Tabelle hinzugefügt wurde und die DAL und BLL entsprechend aktualisiert wurden, können wir eine ASP.NET Seite erstellen, die mit der FullContactName berechneten Spalte funktioniert. Öffnen Sie zunächst die ComputedColumns.aspx Seite im AdvancedDAL Ordner, und ziehen Sie eine GridView aus der Toolbox auf die Designer. Legen Sie die GridView-Eigenschaft ID auf Suppliers fest, und binden Sie sie über das Smarttag an eine neue ObjectDataSource mit dem Namen SuppliersDataSource. Konfigurieren Sie objectDataSource so, dass die Klasse verwendet wird, die SuppliersBLLWithSprocs wir in Schritt 6 hinzugefügt haben, und klicken Sie auf Weiter.

Konfigurieren der ObjectDataSource für die Verwendung der SuppliersBLLWithSprocs-Klasse

Abbildung 11: Konfigurieren der ObjectDataSource für die Verwendung der SuppliersBLLWithSprocs -Klasse (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

In der SuppliersBLLWithSprocs -Klasse sind nur zwei Methoden definiert: GetSuppliers und UpdateSupplier. Stellen Sie sicher, dass diese beiden Methoden auf den Registerkarten SELECT bzw. UPDATE angegeben sind, und klicken Sie auf Fertig stellen, um die Konfiguration der ObjectDataSource abzuschließen.

Nach Abschluss des Assistenten zum Konfigurieren von Datenquellen fügt Visual Studio für jedes zurückgegebene Datenfeld ein BoundField hinzu. Entfernen Sie boundFieldSupplierID, und ändern Sie die HeaderText Eigenschaften von CompanyName, ContactTitleContactName, und FullContactName BoundFields in Unternehmen, Kontaktname, Titel und vollständiger Kontaktname. Aktivieren Sie im Smarttag das Kontrollkästchen Bearbeitung aktivieren, um die integrierten Bearbeitungsfunktionen von GridView zu aktivieren.

Zusätzlich zum Hinzufügen von BoundFields zu GridView bewirkt der Abschluss des Datenquellen-Assistenten auch, dass Visual Studio die ObjectDataSource-Eigenschaft OldValuesParameterFormatString auf original_{0} legt. Setzen Sie diese Einstellung wieder auf den Standardwert zurück. {0}

Nachdem Sie diese Änderungen an GridView und ObjectDataSource ausgeführt haben, sollte ihr deklaratives Markup in etwa wie folgt aussehen:

<asp:GridView ID="Suppliers" runat="server" AutoGenerateColumns="False" 
    DataKeyNames="SupplierID" DataSourceID="SuppliersDataSource">
    <Columns>
        <asp:CommandField ShowEditButton="True" />
        <asp:BoundField DataField="CompanyName" 
            HeaderText="Company" 
            SortExpression="CompanyName" />
        <asp:BoundField DataField="ContactName" 
            HeaderText="Contact Name" 
            SortExpression="ContactName" />
        <asp:BoundField DataField="ContactTitle" 
            HeaderText="Title" 
            SortExpression="ContactTitle" />
        <asp:BoundField DataField="FullContactName" 
            HeaderText="Full Contact Name"
            SortExpression="FullContactName" 
            ReadOnly="True" />
    </Columns>
</asp:GridView>
<asp:ObjectDataSource ID="SuppliersDataSource" runat="server"
    SelectMethod="GetSuppliers" TypeName="SuppliersBLLWithSprocs" 
        UpdateMethod="UpdateSupplier">
    <UpdateParameters>
        <asp:Parameter Name="companyName" Type="String" />
        <asp:Parameter Name="contactName" Type="String" />
        <asp:Parameter Name="contactTitle" Type="String" />
        <asp:Parameter Name="supplierID" Type="Int32" />
    </UpdateParameters>
</asp:ObjectDataSource>

Als Nächstes besuchen Sie diese Seite über einen Browser. Wie Abbildung 12 zeigt, ist jeder Lieferant in einem Raster aufgeführt, das die FullContactName Spalte enthält, deren Wert einfach die Verkettung der anderen drei Spalten ist, die als ContactName (ContactTitle, CompanyName) formatiert sind.

Jeder Lieferant ist im Raster aufgeführt

Abbildung 12: Jeder Lieferant ist im Raster aufgeführt (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Wenn Sie für einen bestimmten Lieferanten auf die Schaltfläche Bearbeiten klicken, wird ein Postback verursacht, und diese Zeile wird in der Bearbeitungsoberfläche gerendert (siehe Abbildung 13). Die ersten drei Spalten werden in ihrer Standardbearbeitungsschnittstelle gerendert: ein TextBox-Steuerelement, dessen Text Eigenschaft auf den Wert des Datenfelds festgelegt ist. Die FullContactName Spalte bleibt jedoch als Text. Als die BoundFields nach Abschluss des Datenquellenkonfigurations-Assistenten zu GridView hinzugefügt wurden, wurde die FullContactName BoundField-Eigenschaft ReadOnly auf true festgelegt, da die entsprechende FullContactName Spalte in der SuppliersDataTable - ReadOnly Eigenschaft auf truefestgelegt ist. Wie in Schritt 4 erwähnt, wurde die FullContactName s-Eigenschaft ReadOnly auf true festgelegt, da der TableAdapter erkannt hat, dass es sich bei der Spalte um eine berechnete Spalte handelt.

Die FullContactName-Spalte kann nicht bearbeitet werden.

Abbildung 13: Die FullContactName Spalte ist nicht bearbeitbar (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Aktualisieren Sie den Wert einer oder mehrerer der bearbeitbaren Spalten, und klicken Sie auf Aktualisieren. Beachten Sie, dass der FullContactName s-Wert automatisch aktualisiert wird, um die Änderung widerzuspiegeln.

Hinweis

GridView verwendet derzeit BoundFields für die bearbeitbaren Felder, was zur Standardbearbeitungsoberfläche führt. Da das CompanyName Feld erforderlich ist, sollte es in ein TemplateField konvertiert werden, das einen RequiredFieldValidator enthält. Ich belasse dies als Übung für den interessierten Leser. Ausführliche Anweisungen zum Konvertieren eines BoundField in ein TemplateField-Objekt und zum Hinzufügen von Validierungssteuerelementen finden Sie im Tutorial Hinzufügen von Validierungssteuerelementen zum Bearbeiten und Einfügen von Schnittstellen .

Zusammenfassung

Beim Definieren des Schemas für eine Tabelle ermöglicht Microsoft SQL Server die Einbeziehung berechneter Spalten. Dabei handelt es sich um Spalten, deren Werte aus einem Ausdruck berechnet werden, der in der Regel auf die Werte aus anderen Spalten im gleichen Datensatz verweist. Da die Werte für berechnete Spalten auf einem Ausdruck basieren, sind sie schreibgeschützt und können in einer INSERT - oder UPDATE -Anweisung nicht zugewiesen werden. Dies führt zu Herausforderungen bei der Verwendung einer berechneten Spalte in der Standard Abfrage eines TableAdapter, die versucht, die entsprechenden INSERTAnweisungen , UPDATEund DELETE automatisch zu generieren.

In diesem Tutorial wurden Techniken zum Umgehen der Herausforderungen durch berechnete Spalten erläutert. Insbesondere haben wir gespeicherte Prozeduren in unserem TableAdapter verwendet, um die Sprödheit zu überwinden, die TableAdapters innewohnt, die Ad-hoc-SQL-Anweisungen verwenden. Wenn der TableAdapter-Assistent neue gespeicherte Prozeduren erstellt, ist es wichtig, dass die Standard Abfrage alle berechneten Spalten zunächst auslässt, da deren Vorhandensein verhindert, dass die gespeicherten Prozeduren zur Datenänderung generiert werden. Nachdem der TableAdapter ursprünglich konfiguriert wurde, kann seine SelectCommand gespeicherte Prozedur so umgerüstet werden, dass alle berechneten Spalten eingeschlossen werden.

Viel Spaß beim Programmieren!

Zum Autor

Scott Mitchell, Autor von sieben ASP/ASP.NET-Büchern und Gründer von 4GuysFromRolla.com, arbeitet seit 1998 mit Microsoft-Webtechnologien. Scott arbeitet als unabhängiger Berater, Trainer und Autor. Sein neuestes Buch ist Sams Teach Yourself ASP.NET 2.0 in 24 Hours. Er kann unter mitchell@4GuysFromRolla.comoder über seinen Blog erreicht werden, der unter http://ScottOnWriting.NETzu finden ist.

Besonderer Dank an

Diese Tutorialreihe wurde von vielen hilfreichen Prüfern überprüft. Leitende Gutachter für dieses Tutorial waren Hilton Geisenow und Teresa Murphy. Möchten Sie meine bevorstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.