Freigeben über


Arbeiten mit berechneten Spalten (VB)

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 in der Regel auf die Werte aus anderen Spalten in derselben Tabelle verweist. Ein Datenmodell für die Zeitnachverfolgung kann beispielsweise eine Tabelle mit dem Namen ServiceLog mit Spalten wie ServicePerformed, EmployeeID, Rateund Durationenthalten. Während der fällige Betrag pro Dienstelement (der mit der Dauer multiplizierte Rate) über eine Webseite oder eine andere programmgesteuerte Schnittstelle berechnet werden kann, kann es praktisch sein, eine Spalte mit dem Namen AmountDue in die Tabelle einzuschließen, die ServiceLog diese Informationen gemeldet hat. Diese Spalte kann als normale Spalte erstellt werden, muss aber bei jeder Änderung der Rate Spaltenwerte oder Duration aktualisiert werden. Ein besserer Ansatz wäre, die AmountDue Spalte mithilfe des Ausdrucks Rate * Durationals berechnete 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 ihnen daher in INSERT - oder UPDATE -Anweisungen keine Werte 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 - und UPDATE -Anweisungen eingeschlossen. Folglich müssen die TableAdapter-Eigenschaften INSERT und UPDATE -Abfragen und und InsertCommandUpdateCommand 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 neu generiert werden, sobald der TableAdapter-Konfigurations-Assistent abgeschlossen ist. Daher werden die berechneten Spalten, die manuell aus und entfernt wurden, INSERTUPDATE wieder angezeigt, wenn der Assistent erneut ausgeführt wird. Obwohl TableAdapters, die gespeicherte Prozeduren verwenden, nicht unter dieser Sprödheit leiden, haben sie ihre eigenen Macken, die in Schritt 3 behandelt 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.

Lassen Sie uns loslegen!

Schritt 1: Hinzufügen einer berechneten Spalte zurSuppliersTabelle

Die Northwind-Datenbank enthält keine berechneten Spalten, sodass wir selbst eine hinzufügen müssen. In diesem Tutorial fügen Sie der Tabelle mit dem Suppliers Namen FullContactName eine berechnete Spalte hinzu, die 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 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. 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 den entsprechenden Ausdruck in das Textfeld (Formel) unter dem Abschnitt Spezifikation berechneter Spalten 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 in SQL mithilfe des + -Operators verkettet werden können. Die CASE -Anweisung kann in einer herkömmlichen Programmiersprache wie eine Bedingung verwendet werden. Im obigen Ausdruck kann die CASE -Anweisung wie folgt gelesen werden: Wenn ContactTitle nicht NULL ist, geben Sie den Wert aus, 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

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. ISNULL In diesem instance funktioniert entweder oderCASE, es gibt jedoch 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 im Menü Datei auf Speichern Suppliersklicken.

Beim Speichern der Tabelle sollte die 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 äquivalenten Ausdruck angepasst, der unnötige Leerzeichen entfernt, Spaltennamen mit Klammern ([]) umschließt und Klammern einschließt, 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. Eine schrittweise exemplarische Vorgehensweise zum Erstellen berechneter Spalten finden Sie auch unter Vorgehensweise: Angeben berechneter Spalten.

Hinweis

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

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 Suppliers Tabelle hinzu, 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 in Abbildung 2 dargestellt, enthalten FullContactNamedie Ergebnisse , die die CompanyNameSpalten , ContactNameund ContactTitle im Format 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 vonSuppliersTableAdapterzur Datenzugriffsebene

Um mit den Lieferanteninformationen in unserer Anwendung arbeiten zu können, müssen wir zunächst 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 TableAdapter-Standard-Abfrage einfügen. Dadurch werden jedoch automatisch Anweisungen und 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 - und UPDATE -Anweisung manuell über die TableAdapter- 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 bei der Arbeit 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 beschrieben. Wenn Sie jedoch vom TableAdapter-Assistenten die gespeicherten Prozeduren für Sie erstellen lassen, ist es wichtig, zunächst alle berechneten Spalten aus der Standard Abfrage auszulassen. 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 den TableAdapter zunächst 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.

In diesem 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 die Designer, und wählen Sie im Kontextmenü aus, um einen neuen TableAdapter hinzuzufügen. Dadurch wird der TableAdapter-Konfigurations-Assistent gestartet. Geben Sie die Datenbank an, aus der Daten abgerufen werden sollen (NORTHWNDConnectionString von 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 klicken Sie auf Weiter.

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

Abbildung 3: Auswählen der Option Neue gespeicherte Prozeduren erstellen (Klicken Sie hier, 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, ContactNameund ContactTitle für jeden Lieferanten zurückgibt. Beachten Sie, dass diese Abfrage die berechnete Spalte (FullContactName) absichtlich auslässt. Wir aktualisieren die entsprechende gespeicherte Prozedur, um diese Spalte in Schritt 4 einzuschließen.

SELECT SupplierID, CompanyName, ContactName, ContactTitle
FROM Suppliers

Nachdem Sie die Standard Abfrage eingegeben und auf Weiter geklickt haben, können wir die vier gespeicherten Prozeduren benennen, die er generiert. Nennen Sie diese gespeicherten Prozeduren Suppliers_Select, Suppliers_InsertSuppliers_Update, und 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 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:

Imports NorthwindWithSprocsTableAdapters
<System.ComponentModel.DataObject()> _
Public Class SuppliersBLLWithSprocs
    Private _suppliersAdapter As SuppliersTableAdapter = Nothing
    Protected ReadOnly Property Adapter() As SuppliersTableAdapter
        Get
            If _suppliersAdapter Is Nothing Then
                _suppliersAdapter = New SuppliersTableAdapter()
            End If
            Return _suppliersAdapter
        End Get
    End Property
    <System.ComponentModel.DataObjectMethodAttribute _
        (System.ComponentModel.DataObjectMethodType.Select, True)> _
    Public Function GetSuppliers() As NorthwindWithSprocs.SuppliersDataTable
        Return Adapter.GetSuppliers()
    End Function
    <System.ComponentModel.DataObjectMethodAttribute _
        (System.ComponentModel.DataObjectMethodType.Update, True)> _
    Public Function UpdateSupplier(companyName As String, contactName As String, _
        contactTitle As String, supplierID As Integer) As Boolean
        Dim suppliers As NorthwindWithSprocs.SuppliersDataTable = _
            Adapter.GetSupplierBySupplierID(supplierID)
        If suppliers.Count = 0 Then
            ' no matching record found, return false
            Return False
        End If
        Dim supplier As NorthwindWithSprocs.SuppliersRow = suppliers(0)
        supplier.CompanyName = companyName
        If contactName Is Nothing Then 
            supplier.SetContactNameNull() 
        Else 
            supplier.ContactName = contactName
        End If
        If contactTitle Is Nothing Then 
            supplier.SetContactTitleNull() 
        Else 
            supplier.ContactTitle = contactTitle
        End If
        ' Update the product record
        Dim rowsAffected As Integer = Adapter.Update(supplier)
        ' Return true if precisely one row was updated, otherwise false
        Return rowsAffected = 1
    End Function
End Class

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 vorliegenNothing, 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.

Besonderen 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 anstehenden MSDN-Artikel lesen? Wenn dies der Fall ist, legen Sie eine Zeile unter abmitchell@4GuysFromRolla.com.