Arbeiten mit berechneten Spalten (VB)
von Scott Mitchell
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
, Rate
und Duration
enthalten. 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 * Duration
als 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 InsertCommand
UpdateCommand
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, INSERT
UPDATE
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 zurSuppliers
Tabelle
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.
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 Suppliers
klicken.
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 CompanyName
Spalten , ContactName
, ContactTitle
und 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 FullContactName
die Ergebnisse , die die CompanyName
Spalten , ContactName
und ContactTitle
im Format ContactName
(ContactTitle
, CompanyName
) auflistet.
Abbildung 2: Verwendet FullContactName
das Format ContactName
(ContactTitle
, CompanyName
) (Klicken Sie hier, um das Bild in voller Größe anzuzeigen)
Schritt 3: Hinzufügen vonSuppliersTableAdapter
zur 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 UseJOIN
s 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.
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 SupplierID
Spalten , CompanyName
, ContactName
und 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_Insert
Suppliers_Update
, und Suppliers_Delete
, wie in Abbildung 4 dargestellt.
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.
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:
- Aktualisieren der
Suppliers_Select
gespeicherten Prozedur, um dieFullContactName
berechnete Spalte zurückzugeben, und - 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 , SuppliersTableAdapter
und wählen Sie im Kontextmenü Konfigurieren aus. Beachten Sie, dass die Suppliers_Select
Spalte jetzt die Spalte in der FullContactName
Datenspaltenauflistung enthält.
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 true
festgelegt. 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 DataType
MaxLength
-eigenschaften ebenfalls entsprechend festgelegt sind.
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 einerGetSupplierBySupplierID
Methode 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.
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.
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
.
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 Protected
Adapter
-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 CategoryName
Eigenschaften , ContactName
und 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 CompanyName
lassen 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.
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
, ContactTitle
ContactName
, 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.
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 True
festgelegt 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.
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 INSERT
Anweisungen , UPDATE
und 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.
Feedback
https://aka.ms/ContentUserFeedback.
Bald verfügbar: Im Laufe des Jahres 2024 werden wir GitHub-Issues stufenweise als Feedbackmechanismus für Inhalte abbauen und durch ein neues Feedbacksystem ersetzen. Weitere Informationen finden Sie unterFeedback senden und anzeigen für