Freigeben über


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 in der Regel auf andere Werte im selben Datenbankdatensatz verweist. Solche Werte sind in der Datenbank schreibgeschützt, was bei der Arbeit mit TableAdapters besondere Überlegungen erfordert. In diesem Lernprogramm erfahren Sie, wie Sie die Herausforderungen von berechneten Spalten bewältigen können.

Einführung

Microsoft SQL Server ermöglicht berechnete Spalten, bei denen es sich um Spalten handelt, deren Werte aus einem Ausdruck berechnet werden, der in der Regel auf die Werte aus anderen Spalten in derselben Tabelle verweist. Ein Datenmodell für die Zeitverfolgung kann beispielsweise eine Tabelle ServiceLog mit Spalten wie ServicePerformed, , EmployeeID, Rateund , u Duration. a. enthalten. Während der fällige Betrag pro Dienstelement (wobei die Rate mit der Dauer multipliziert wird) über eine Webseite oder eine andere programmgesteuerte Schnittstelle berechnet werden kann, kann es praktisch sein, eine Spalte in die Tabelle AmountDue einzuschließen, die ServiceLog diese Informationen gemeldet hat. Diese Spalte könnte als normale Spalte erstellt werden, muss aber bei jeder Änderung der Rate Duration Spaltenwerte aktualisiert werden. 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 den AmountDue Spaltenwert automatisch berechnet, wenn in einer Abfrage darauf verwiesen wurde.

Da ein berechneter Spaltenwert durch einen Ausdruck bestimmt wird, sind solche Spalten schreibgeschützt und können daher keine Werte enthalten, die ihnen in INSERT oder UPDATE Anweisungen zugewiesen werden. Wenn berechnete Spalten jedoch Teil der Hauptabfrage für einen TableAdapter sind, der Ad-hoc-SQL-Anweisungen verwendet, werden sie automatisch in die automatisch generierten INSERT und UPDATE Anweisungen einbezogen. Folglich müssen die TableAdapter-Elemente INSERT und -Abfragen und UPDATE InsertCommand UpdateCommand -Eigenschaften aktualisiert werden, um Verweise auf berechnete Spalten zu entfernen.

Eine Herausforderung bei der Verwendung berechneter Spalten mit einem TableAdapter, der Ad-hoc-SQL-Anweisungen verwendet, besteht darin, dass die TableAdapter-Elemente INSERT und UPDATE -Abfragen bei Abschluss des TableAdapter-Konfigurations-Assistenten automatisch neu generiert werden. Daher werden die berechneten Spalten, die manuell aus den INSERT und UPDATE Abfragen entfernt werden, wieder angezeigt, wenn der Assistent erneut ausgeführt wird. Obwohl TableAdapters, die gespeicherte Prozeduren verwenden, nicht unter dieser Sprödigkeit leiden, haben sie ihre eigenen Eigenheiten, die wir in Schritt 3 behandeln werden.

In diesem Lernprogramm fügen wir der Tabelle in der Suppliers Northwind-Datenbank eine berechnete Spalte hinzu und erstellen dann einen entsprechenden TableAdapter für die Arbeit mit dieser Tabelle und deren berechnete Spalte. Wir verwenden gespeicherte Prozeduren anstelle von Ad-hoc-SQL-Anweisungen, damit unsere Anpassungen beim Verwenden des TableAdapter-Konfigurations-Assistenten nicht verloren gehen.

Los geht's!

Schritt 1: Hinzufügen einer berechneten Spalte zurSuppliersTabelle

Die Northwind-Datenbank verfügt nicht über berechnete Spalten, daher müssen wir eines selbst hinzufügen. In diesem Lernprogramm fügen wir der Tabelle eine berechnete Spalte hinzu, die Suppliers den Namen, den Titel und das Unternehmen zurückgibt, für das sie im folgenden Format arbeiten: ContactName (ContactTitle, CompanyName).FullContactName Diese berechnete Spalte kann in Berichten verwendet werden, wenn Informationen zu Lieferanten angezeigt werden.

Öffnen Sie zunächst die Suppliers Tabellendefinition, indem Sie im Server-Explorer mit der rechten Maustaste auf die Suppliers Tabelle klicken und im Kontextmenü "Tabellendefinition öffnen" auswählen. Dadurch werden die Spalten der Tabelle und deren Eigenschaften angezeigt, z. B. deren Datentyp, ob sie zulassen NULL usw. Wenn Sie eine berechnete Spalte hinzufügen möchten, geben Sie zunächst den Namen der Spalte in die Tabellendefinition ein. Geben Sie als Nächstes ihren Ausdruck in das Textfeld (Formel) unter dem Abschnitt "Berechnete Spaltenspezifikation" in der Spalte Eigenschaftenfenster 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 mithilfe des + Operators 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 wie folgt gelesen werden: Wenn ContactTitle der Wert nicht NULL ausgegeben wird, der ContactTitle mit einem Komma verkettet ist, andernfalls wird nichts ausgegeben. Weitere Informationen zur Nützlichkeit der CASE Anweisung finden Sie unter SQL-AnweisungenCASE.

Hinweis

Statt hier eine CASE Aussage zu verwenden, könnten wir alternativ verwendet ISNULL(ContactTitle, '')werden. ISNULL(checkExpression, replacementValue)gibt checkExpression zurück, wenn es nicht NULL ist, andernfalls wird replacementValue zurückgegeben. Zwar funktioniert dies ISNULL CASE in dieser Instanz, es gibt jedoch komplexere Szenarien, in denen die Flexibilität der CASE Anweisung nicht abgeglichen ISNULLwerden 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

Abbildung 1: Hinzufügen einer berechneten Spalte namens FullContactName " Suppliers Tabelle" (Zum Anzeigen des Bilds mit voller Größe klicken)

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

Beim Speichern der Tabelle sollte der Server-Explorer aktualisiert werden, 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 in eckige Klammern ([]) einschließt und Klammern enthält, um die Reihenfolge der Vorgänge explizit 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 außerdem die Vorgehensweise an: Angeben berechneter Spalten für eine schrittweise exemplarische Vorgehensweise zum Erstellen berechneter Spalten.

Hinweis

Berechnete Spalten werden standardmäßig nicht physisch in der Tabelle gespeichert, sondern bei jedem Verweis in einer Abfrage neu berechnet. Durch Aktivieren des Kontrollkästchens "Beibehalten" können Sie SQL Server jedoch anweisen, die berechnete Spalte in der Tabelle physisch zu speichern. Auf diese Weise kann ein Index in der berechneten 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 berechneten Spaltenwerte

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

Wie in Abbildung 2 dargestellt, sind die Ergebnisse enthalten FullContactName, in denen die CompanyNameSpalten ContactNameund ContactTitle das Format ldquo;ContactName (ContactTitle, CompanyName) aufgeführt sind.

Der FullContactName verwendet das Format ContactName (ContactTitle, CompanyName)

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

Schritt 3: Hinzufügen derSuppliersTableAdapterDatenzugriffsebene

Um mit den Lieferanteninformationen in unserer Anwendung zu arbeiten, müssen wir zuerst eine TableAdapter und DataTable in unserer DAL erstellen. Im Idealfall wäre dies mit den gleichen einfachen Schritten zu erreichen, die in früheren Lernprogrammen untersucht wurden. Die Arbeit mit berechneten Spalten führt jedoch zu einigen Falten, die diskussionswürdig sind.

Wenn Sie ein TableAdapter verwenden, das Ad-hoc-SQL-Anweisungen verwendet, können Sie einfach die berechnete Spalte in die TableAdapter-Hauptabfrage über den TableAdapter-Konfigurations-Assistenten einschließen. Dies wird jedoch automatisch generiert INSERT und UPDATE Anweisungen, die die berechnete Spalte enthalten. Wenn Sie versuchen, eine dieser Methoden auszuführen, kann die SqlException Meldung "ColumnName" nicht geändert werden, da es sich entweder um eine berechnete Spalte handelt oder das Ergebnis eines UNION-Operators ausgelöst wird. Während die INSERT Und-Anweisung UPDATE manuell über die TableAdapter s 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 Lernprogramm "Using Existing Stored Procedures for The Typed DataSet s TableAdapters " beschrieben. Wenn Sie den TableAdapter-Assistenten zum Erstellen der gespeicherten Prozeduren für Sie haben, ist es jedoch wichtig, zunächst alle berechneten Spalten aus der Hauptabfrage auszulassen. Wenn Sie eine berechnete Spalte in die Hauptabfrage einschließen, informiert Sie der Konfigurations-Assistent von TableAdapter nach Abschluss, dass die entsprechenden gespeicherten Prozeduren nicht erstellt werden können. Kurz gesagt müssen wir zunächst den TableAdapter mithilfe einer berechneten spaltenfreien Hauptabfrage 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 Lernprogramm "TableAdapter to UseJOINs" verwendet wird.

Für dieses Lernprogramm fügen wir ein neues TableAdapter hinzu und lassen Sie es automatisch die gespeicherten Prozeduren für uns erstellen. Daher müssen wir zunächst die FullContactName berechnete Spalte aus der Hauptabfrage weglassen.

Öffnen Sie zunächst das NorthwindWithSprocs DataSet im ~/App_Code/DAL Ordner. Klicken Sie im Designer mit der rechten Maustaste, und wählen Sie im Kontextmenü ein neues TableAdapter-Objekt aus. Dadurch wird der Konfigurations-Assistent "TableAdapter" gestartet. Geben Sie die Datenbank an, aus der Daten abgerufen werden sollen (NORTHWNDConnectionString aus Web.config) 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 auf "Weiter" klickt.

Wählen Sie die Option

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

Der folgende Schritt fordert uns zur Hauptabfrage auf. Geben Sie die folgende Abfrage ein, die die SupplierIDSpalten CompanyName, , ContactNameund ContactTitle die Spalten für jeden Lieferanten zurückgibt. Beachten Sie, dass diese Abfrage die berechnete Spalte (FullContactName) absichtlich ausgelassen. Wir aktualisieren die entsprechende gespeicherte Prozedur so, dass sie diese Spalte in Schritt 4 einschließt.

SELECT SupplierID, CompanyName, ContactName, ContactTitle
FROM Suppliers

Nachdem Sie die Hauptabfrage eingegeben und auf "Weiter" geklickt haben, kann der Assistent die vier gespeicherten Prozeduren benennen, die generiert werden. Nennen Sie diese gespeicherten Prozeduren Suppliers_Select, Suppliers_Insert, Suppliers_Updateund Suppliers_Delete, wie in Abbildung 4 dargestellt.

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 GetSuppliersjedoch in . Klicken Sie auf Fertig stellen, um den Assistenten abzuschließen.

Umbenennen der GetData-Methode in

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

Wenn Sie auf "Fertig stellen" klicken, erstellt der Assistent die vier gespeicherten Prozeduren und fügt das TableAdapter und die entsprechende DataTable zum typierten DataSet hinzu.

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

Wir müssen nun das in Schritt 3 erstellte TableAdapter- und DataTable-Objekt 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 so, dass sie die FullContactName berechnete Spalte enthält:

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

Speichern Sie die Änderungen an der gespeicherten Prozedur, indem Sie auf das Symbol "Speichern" in der Symbolleiste klicken, indem Sie 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 SuppliersTableAdapterrechten Maustaste darauf, und wählen Sie im Kontextmenü "Konfigurieren" aus. Beachten Sie, dass die Suppliers_Select Spalte jetzt die Spalte in der FullContactName Datenspaltenauflistung enthält.

Ausführen des Konfigurations-Assistenten für TableAdapters zum Aktualisieren der Datentabellenspalten

Abbildung 6: Ausführen des Konfigurations-Assistenten für TableAdapter zum Aktualisieren der Datentabellenspalten (Klicken, 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 und daher schreibgeschützt ist. Folglich wird die Eigenschaft der Spalte ReadOnly auf true. Um dies zu überprüfen, wählen Sie die Spalte aus, SuppliersDataTable und wechseln Sie dann zum Eigenschaftenfenster (siehe Abbildung 7). Beachten Sie, dass die FullContactName Spalten DataType und MaxLength Eigenschaften ebenfalls entsprechend festgelegt werden.

Die Spalte

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

Schritt 5: Hinzufügen einerGetSupplierBySupplierIDMethode zum TableAdapter

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

Klicken Sie mit der rechten Maustaste auf das SuppliersTableAdapter DataSet-Design, und wählen Sie im Kontextmenü die Option "Abfrage hinzufügen" aus. Wie in Schritt 3 beschrieben, lassen Sie den Assistenten eine neue gespeicherte Prozedur für uns generieren, indem Sie die Option "Neue gespeicherte Prozedur erstellen" auswählen (siehe Abbildung 3 für einen Screenshot dieses Assistentenschritts). Da diese Methode einen Datensatz mit mehreren Spalten zurückgibt, geben Sie an, dass wir eine SQL-Abfrage verwenden möchten, die eine SELECT ist, die Zeilen zurückgibt, und klicken Sie auf Weiter.

Choose the SELECT which returns rows Option

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

Der folgende Schritt fordert uns auf, die Abfrage für diese Methode zu verwenden. Geben Sie Folgendes ein, das dieselben Datenfelder wie die Hauptabfrage, aber für einen bestimmten Lieferanten zurückgibt.

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

Im 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 der gespeicherten 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 auf, die Datenzugriffsmuster und Methodennamen für den TableAdapter zu verwenden. Lassen Sie beide Kontrollkästchen aktiviert, benennen Sie die FillBy Methoden GetDataBy FillBySupplierID jedoch in bzw GetSupplierBySupplierID. um.

Benennen der TableAdapter-Methoden FillBySupplierID und GetSupplierBySupplierID

Abbildung 10: Benennen der TableAdapter-Methoden FillBySupplierID und GetSupplierBySupplierID (Klicken Sie, 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 zuerst die entsprechenden Methoden in der BLL hinzufügen. Auf unserer ASP.NET-Seite, 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 eine andere 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;
    }
}

Wie bei den anderen BLL-Klassen gibt es eine Adapter protected Eigenschaft, SuppliersBLLWithSprocs die eine Instanz der SuppliersTableAdapter Klasse zusammen mit zwei public Methoden zurückgibt: GetSuppliers und UpdateSupplier. Die GetSuppliers Methode ruft die SuppliersDataTable von der entsprechenden GetSupplier Methode in der Datenzugriffsschicht zurückgegebene Methode auf und gibt sie zurück. Die UpdateSupplier Methode ruft Informationen über den jeweiligen Lieferanten ab, der über einen Aufruf der DAL s-Methode GetSupplierBySupplierID(supplierID) aktualisiert wird. Anschließend werden die Änderungen an der CategoryNameDatenbank aktualisiert und ContactTitle durch Aufrufen der Data Access Layer-Methode Update und übergeben sie das geänderte SuppliersRow ContactNameObjekt.

Hinweis

Mit Ausnahme und SupplierID CompanyName, dass alle Spalten in der Tabelle "Lieferanten" Werte zulassen NULL . Wenn also die übergebenen contactName oder contactTitle Parameter übergeben werden null , müssen wir die entsprechenden ContactName Eigenschaften ContactTitle bzw. Eigenschaften auf einen NULL Datenbankwert festlegen, der bzw. die SetContactNameNull SetContactTitleNull methoden verwendet wird.

Schritt 7: Arbeiten mit der berechneten Spalte aus 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 den Designer. Legen Sie die GridView-Eigenschaft ID auf und binden Sie sie von ihrem Smarttag an Suppliers eine neue ObjectDataSource mit dem Namen SuppliersDataSource. Konfigurieren Sie die ObjectDataSource so, dass sie die Klasse verwendet, die SuppliersBLLWithSprocs wir in Schritt 6 wieder 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 Klasse (Zum Anzeigen des SuppliersBLLWithSprocs Bilds mit voller Größe klicken)

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

Nach Abschluss des Assistenten für die Datenquellenkonfiguration fügt Visual Studio für jedes der zurückgegebenen Datenfelder ein BoundField hinzu. Entfernen Sie das SupplierID BoundField, und ändern Sie die HeaderText Eigenschaften von " CompanyName, ContactName" , ContactTitle" und FullContactName "BoundFields" in "Company", "Contact Name", "Title" bzw. "Vollständiger Kontaktname". Aktivieren Sie im Smarttag das Kontrollkästchen "Bearbeitung aktivieren", um die integrierten Bearbeitungsfunktionen von GridView zu aktivieren.

Neben dem Hinzufügen von BoundFields zur GridView bewirkt der Abschluss des Datenquellen-Assistenten auch, dass Visual Studio die ObjectDataSource-Eigenschaft OldValuesParameterFormatString auf original_{0} festgelegt. Setzen Sie diese Einstellung auf den Standardwert zurück. {0}

Nachdem Sie diese Änderungen an GridView und ObjectDataSource vorgenommen haben, sollte ihr deklaratives Markup 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>

Besuchen Sie als Nächstes diese Seite über einen Browser. Wie in Abbildung 12 dargestellt, wird 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 aufgelistet (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)

Durch Klicken auf die Schaltfläche "Bearbeiten" für einen bestimmten Lieferanten wird ein Postback verursacht und die Zeile in der Bearbeitungsoberfläche gerendert (siehe Abbildung 13). Die ersten drei Spalten werden in der Standardbearbeitungsschnittstelle gerendert – ein TextBox-Steuerelement, dessen Text Eigenschaft auf den Wert des Datenfelds festgelegt ist. Die FullContactName Spalte bleibt jedoch als Text. Wenn die BoundFields nach Abschluss des Assistenten für die Datenquellenkonfiguration der GridView hinzugefügt wurden, wurde die FullContactName BoundField-Eigenschaft ReadOnly so festgelegt true , dass die entsprechende FullContactName Spalte in der SuppliersDataTable Eigenschaft auf ReadOnly /> festgelegt trueist. Wie in Schritt 4 erwähnt, wurde die FullContactName s-Eigenschaft ReadOnly so festgelegt true , dass das TableAdapter festgestellt hat, dass die Spalte eine berechnete Spalte war.

Die Spalte

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

Fahren Sie fort, und aktualisieren Sie den Wert einer oder mehrerer bearbeitbarer Spalten, und klicken Sie auf "Aktualisieren". Beachten Sie, wie der FullContactName Wert automatisch aktualisiert wird, um die Änderung widerzuspiegeln.

Hinweis

GridView verwendet derzeit BoundFields für die bearbeitbaren Felder, was zu der Standardbearbeitungsschnittstelle führt. Da das CompanyName Feld erforderlich ist, sollte es in ein TemplateField konvertiert werden, das ein RequiredFieldValidator enthält. Ich belässt dies als Übung für den interessierten Leser. Lesen Sie das Lernprogramm zum Hinzufügen von Gültigkeitsprüfungssteuerelementen zum Lernprogramm zum Bearbeiten und Einfügen von Schnittstellen , um schrittweise Anleitungen zum Konvertieren eines BoundField-Steuerelements in ein TemplateField und zum Hinzufügen von Überprüfungssteuerelementen zu erhalten.

Zusammenfassung

Beim Definieren des Schemas für eine Tabelle ermöglicht Microsoft SQL Server die Aufnahme berechneter Spalten. Dies sind Spalten, deren Werte aus einem Ausdruck berechnet werden, der in der Regel auf die Werte aus anderen Spalten im selben Datensatz verweist. Da die Werte für berechnete Spalten auf einem Ausdruck basieren, sind sie schreibgeschützt und können einem Wert in einer INSERT Oder-Anweisung UPDATE nicht zugewiesen werden. Dies führt zu Herausforderungen bei der Verwendung einer berechneten Spalte in der Hauptabfrage eines TableAdapters, die versucht, automatisch entsprechende INSERT, und UPDATEDELETE Anweisungen zu generieren.

In diesem Lernprogramm haben wir Techniken zur Umgehung der Herausforderungen durch berechnete Spalten erörtert. Insbesondere haben wir gespeicherte Prozeduren in unserem TableAdapter verwendet, um die Inhärenz von TableAdapters zu überwinden, die Ad-hoc-SQL-Anweisungen verwenden. Wenn der TableAdapter-Assistent neue gespeicherte Prozeduren erstellt hat, ist es wichtig, dass die Hauptabfrage zunächst berechnete Spalten weglassen muss, da deren Anwesenheit verhindert, dass die gespeicherten Prozeduren für die Datenänderung generiert werden. Nachdem das TableAdapter-Objekt ursprünglich konfiguriert wurde, kann die SelectCommand gespeicherte Prozedur umgerüstet werden, um berechnete Spalten einzuschließen.

Glückliche Programmierung!

Zum Autor

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

Besonderer Dank an

Diese Lernprogrammreihe wurde von vielen hilfreichen Prüfern überprüft. Leitende Prüfer für dieses Lernprogramm waren Hilton Geisenow und Teresa Murphy. Möchten Sie meine bevorstehenden MSDN-Artikel überprüfen? Wenn dies der Fall ist, legen Sie mir eine Zeile bei mitchell@4GuysFromRolla.com.