Condividi tramite


Uso di colonne calcolate (VB)

di Scott Mitchell

Scaricare il PDF

Quando si crea una tabella di database, Microsoft SQL Server consente di definire una colonna calcolata il cui valore viene calcolato da un'espressione che in genere fa riferimento ad altri valori nello stesso record di database. Tali valori sono di sola lettura nel database, che richiede considerazioni speciali quando si lavora con TableAdapters. In questa esercitazione viene illustrato come soddisfare le sfide poste dalle colonne calcolate.

Introduzione

Microsoft SQL Server consente colonne calcolate, ovvero colonne i cui valori vengono calcolati da un'espressione che in genere fa riferimento ai valori di altre colonne della stessa tabella. Ad esempio, un modello di dati di rilevamento dell'ora potrebbe avere una tabella denominata ServiceLog con colonne tra cui ServicePerformed, EmployeeIDRate, e Duration, tra le altre. Anche se l'importo dovuto per ogni elemento di servizio (moltiplicato per la durata) può essere calcolato tramite una pagina Web o un'altra interfaccia programmatica, potrebbe essere utile includere una colonna nella ServiceLog tabella denominata AmountDue che ha segnalato queste informazioni. Questa colonna può essere creata come colonna normale, ma deve essere aggiornata ogni volta che i valori di Rate colonna o Duration sono stati modificati. Un approccio migliore sarebbe quello di rendere la AmountDue una colonna calcolata utilizzando l'espressione Rate * Duration. In questo modo SQL Server calcola automaticamente il valore della AmountDue colonna ogni volta che viene fatto riferimento in una query.

Poiché il valore di una colonna calcolata è determinato da un'espressione, tali colonne sono di sola lettura e pertanto non possono avere valori assegnati a loro nelle istruzioni INSERT o UPDATE. Tuttavia, quando le colonne calcolate fanno parte della query principale per un TableAdapter che usa istruzioni SQL ad hoc, vengono incluse automaticamente nelle istruzioni INSERT e UPDATE generate automaticamente. Di conseguenza, le query INSERT e UPDATE e le proprietà InsertCommand e UpdateCommand del TableAdapter devono essere aggiornate per rimuovere i riferimenti a qualsiasi colonna calcolata.

Una delle difficoltà nell'uso di colonne calcolate con un TableAdapter che usa istruzioni SQL ad hoc consiste nel fatto che le query INSERT e UPDATE del TableAdapter vengono rigenerate automaticamente ogni volta che viene completata la procedura guidata di configurazione del TableAdapter. Pertanto, le colonne calcolate rimosse manualmente dalle query INSERT e UPDATE verranno nuovamente visualizzate se la procedura guidata viene rieseguita. Anche se gli oggetti TableAdapter che utilizzano le stored procedure non risentono di questa fragilità, presentano le loro stranezze che affronteremo nel Passaggio 3.

In questa esercitazione si aggiungerà una colonna calcolata alla Suppliers tabella nel database Northwind e quindi si creerà un TableAdapter corrispondente per lavorare con questa tabella e la relativa colonna calcolata. In TableAdapter verranno usate stored procedure anziché istruzioni SQL ad hoc, in modo che le personalizzazioni non andranno perse quando viene usata la Configurazione guidata TableAdapter.

Iniziamo!

Passaggio 1: Aggiunta di una colonna calcolata allaSupplierstabella

Il database Northwind non dispone di colonne calcolate, quindi sarà necessario aggiungerne uno. Per questa esercitazione è possibile aggiungere una colonna calcolata alla Suppliers tabella denominata FullContactName che restituisce il nome, il titolo e la società per cui lavorano nel formato seguente: ContactName (ContactTitle, CompanyName). Questa colonna calcolata può essere usata nei report quando vengono visualizzate informazioni sui fornitori.

Inizia aprendo la definizione della Suppliers tabella facendo clic con il pulsante destro del mouse sulla Suppliers tabella in Esplora Server e scegliendo Apri definizione tabella dal menu di scelta rapida. Verranno visualizzate le colonne della tabella e le relative proprietà, ad esempio il tipo di dati, se consentono i NULL e così via. Per aggiungere una colonna calcolata, iniziare digitando il nome della colonna nella definizione della tabella. Successivamente, immettere l'espressione nella casella di testo (Formula) sotto la sezione specifica della colonna calcolata nella finestra Proprietà delle colonne (vedere la Figura 1). Denominare la colonna FullContactName calcolata e usare l'espressione seguente:

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

Si noti che le stringhe possono essere concatenate in SQL usando l'operatore + . L'istruzione CASE può essere usata come condizionale in un linguaggio di programmazione tradizionale. Nell'espressione precedente, l'istruzione CASE può essere letta come: Se ContactTitle non è NULL, allora emetti il valore di ContactTitle concatenato con una virgola; altrimenti, non emettere nulla. Per altre informazioni sull'utilità dell'istruzioneCASE, vedere Istruzioni SQLCASE.

Nota

Invece di usare un'istruzione CASE in questo caso, è possibile usare ISNULL(ContactTitle, '')in alternativa . ISNULL(checkExpression, replacementValue) restituisce checkExpression se non è NULL, in caso contrario restituisce replacementValue. Sebbene sia ISNULL che CASE funzionino in questo caso, esistono scenari più complessi in cui la flessibilità dell'istruzione CASE non può essere eguagliata da ISNULL.

Dopo aver aggiunto questa colonna calcolata, la schermata dovrebbe essere simile alla schermata nella figura 1.

Aggiungere una colonna calcolata denominata FullContactName alla tabella Suppliers

Figura 1: Aggiungere una colonna calcolata denominata FullContactName alla tabella (Suppliers a dimensione intera)

Dopo aver assegnare un nome alla colonna calcolata e immetterne l'espressione, salvare le modifiche apportate alla tabella facendo clic sull'icona Salva sulla barra degli strumenti, premendo CTRL+S oppure passando al menu File e scegliendo Salva Suppliers.

Salvando la tabella si aggiorna Esplora server, inclusa nell'elenco delle colonne della tabella la colonna appena aggiunta Suppliers. Inoltre, l'espressione immessa nella casella di testo (Formula) verrà adattata automaticamente a un'espressione equivalente che rimuove spazi vuoti non necessari, racchiude i nomi di colonna tra parentesi ([]) e include parentesi per mostrare in modo più esplicito l'ordine delle operazioni:

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

Per altre informazioni sulle colonne calcolate in Microsoft SQL Server, vedere la documentazione tecnica. Vedere anche Procedura : Specificare le colonne calcolate per una procedura dettagliata per la creazione di colonne calcolate.

Nota

Per impostazione predefinita, le colonne calcolate non vengono archiviate fisicamente nella tabella, ma vengono ricalcolate ogni volta che viene fatto riferimento a una query. Selezionando la casella di controllo È persistente, è tuttavia possibile indicare a SQL Server di archiviare fisicamente la colonna calcolata nella tabella. In questo modo è possibile creare un indice nella colonna calcolata, che può migliorare le prestazioni delle query che usano il valore della colonna calcolata nelle relative WHERE clausole. Per altre informazioni, vedere Creazione di indici in colonne calcolate .

Passaggio 2: Visualizzazione dei valori delle colonne calcolate

Prima di iniziare a lavorare sul livello di accesso ai dati, prendiamoci un minuto per visualizzare i valori FullContactName. In Esplora server fare clic con il pulsante destro del mouse sul nome della Suppliers tabella e scegliere Nuova query dal menu di scelta rapida. Verrà visualizzata una finestra Query che richiede di scegliere le tabelle da includere nella query. Aggiungere la Suppliers tabella e fare clic su Chiudi. Controllare quindi le CompanyNamecolonne , ContactName, ContactTitlee FullContactName della tabella Suppliers. Infine, fare clic sull'icona punto esclamativo rosso nella barra degli strumenti per eseguire la query e visualizzare i risultati.

Come illustrato nella figura 2, i risultati includono FullContactName, che elenca le CompanyNamecolonne , ContactNamee ContactTitle usando il formato ContactName (ContactTitle, CompanyName).

FullContactName usa il formato ContactName (ContactTitle, CompanyName)

Figura 2: FullContactName Usa il formato ContactName (, ContactTitle) (CompanyNamefare clic per visualizzare l'immagine a dimensione intera)

Passaggio 3: Aggiunta diSuppliersTableAdapteral livello di accesso ai dati

Per lavorare con le informazioni sul fornitore nell'applicazione, è necessario prima creare un oggetto TableAdapter e DataTable in DAL. Idealmente, questa operazione verrebbe eseguita usando gli stessi passaggi semplici esaminati nelle esercitazioni precedenti. Tuttavia, l'uso delle colonne calcolate introduce alcune complicazioni che meritano una discussione.

Se si usa un TableAdapter che usa istruzioni SQL ad hoc, è sufficiente includere la colonna calcolata nella query principale di TableAdapter tramite la Configurazione guidata TableAdapter. Tuttavia, verranno generate automaticamente istruzioni INSERT e UPDATE che includono la colonna calcolata. Se si tenta di eseguire uno di questi metodi, verrà generata un'eccezione con il messaggio La colonna SqlException non può essere modificata perché è una colonna calcolata o è il risultato di un operatore UNION. Anche se l'istruzione INSERT e UPDATE può essere modificata manualmente tramite le proprietà InsertCommand e UpdateCommand di TableAdapter, queste personalizzazioni andranno perse ogni volta che la Configurazione guidata TableAdapter viene eseguita di nuovo.

A causa della fragilità dei TableAdapter che usano istruzioni SQL ad hoc, è consigliabile usare stored procedure quando si usano colonne calcolate. Se si utilizzano stored procedure esistenti, è sufficiente configurare il TableAdapter come descritto nell'esercitazione "Uso di stored procedure esistenti con i TableAdapters del DataSet tipizzato". Se la procedura guidata TableAdapter crea automaticamente le stored procedure, è tuttavia importante omettere inizialmente tutte le colonne calcolate dalla query principale. Se si include una colonna calcolata nella query principale, la procedura guidata di configurazione del TableAdapter informerà, al termine, che non può creare le procedure memorizzate corrispondenti. In breve, è necessario configurare inizialmente il TableAdapter usando una query principale senza colonna calcolata e quindi aggiornare manualmente la stored procedure corrispondente e il TableAdapter per includere la colonna calcolata SelectCommand. Questo approccio è simile a quello usato nell'esercitazione Aggiornamento di TableAdapter per l'utilizzo nel tutorial JOINs.

Per questa esercitazione, aggiungiamo un nuovo TableAdapter e lasciamolo creare automaticamente le stored procedure per noi. Di conseguenza, sarà inizialmente necessario omettere la FullContactName colonna calcolata dalla query principale.

Per iniziare, aprire l'oggetto NorthwindWithSprocs DataSet nella ~/App_Code/DAL cartella . Fare clic con il pulsante destro del mouse in Progettazione e scegliere di aggiungere un nuovo oggetto TableAdapter dal menu di scelta rapida. Verrà avviata la procedura guidata di configurazione del TableAdapter. Specificare il database per eseguire query sui dati da (NORTHWNDConnectionString da Web.config) e fare clic su Avanti. Poiché non abbiamo ancora creato stored procedure per l'esecuzione di query o la modifica della tabella Suppliers, selezionare l'opzione Crea nuove stored procedure in modo che la procedura guidata le crei per noi e fare clic su Avanti.

Scegliere l'opzione Crea nuove stored procedure

Figura 3: Scegliere l'opzione Crea nuove stored procedure (fare clic per visualizzare l'immagine a dimensione intera)

Il passaggio successivo ci invita a fornire la query principale. Immettere la query seguente, che restituisce le colonne SupplierID, CompanyName, ContactName e ContactTitle per ogni fornitore. Si noti che questa query omette intenzionalmente la colonna calcolata (FullContactName); la stored procedure corrispondente verrà aggiornata in modo da includere questa colonna nel passaggio 4.

SELECT SupplierID, CompanyName, ContactName, ContactTitle
FROM Suppliers

Dopo aver immesso la query principale e aver fatto clic su Avanti, la procedura guidata consente di dare un nome alle quattro stored procedure che genererà. Denominare queste stored procedure Suppliers_Select, Suppliers_Insert, Suppliers_Update, e Suppliers_Delete, come illustra la Figura 4.

Personalizzare i nomi delle stored procedure generate automaticamente

Figura 4: Personalizzare i nomi delle stored procedure generate automaticamente (fare clic per visualizzare l'immagine a dimensione intera)

Il passaggio successivo della procedura guidata consente di denominare i metodi di TableAdapter e specificare i modelli usati per accedere ai dati e aggiornarli. Lasciare selezionate tutte e tre le caselle di controllo, ma rinominare il GetData metodo in GetSuppliers. Fare clic su Fine per completare la procedura guidata.

Rinominare il metodo GetData in GetSuppliers

Figura 5: Rinominare il GetData metodo in GetSuppliers (fare clic per visualizzare l'immagine a dimensione intera)

Dopo aver fatto clic su Fine, la procedura guidata creerà le quattro stored procedure e aggiungerà il TableAdapter e la DataTable corrispondente all'oggetto DataSet tipizzato.

Passaggio 4: Inclusione della colonna calcolata nella query principale di TableAdapter

A questo punto è necessario aggiornare TableAdapter e DataTable creati nel passaggio 3 per includere la FullContactName colonna calcolata. Questa operazione comporta due passaggi:

  1. Aggiornamento della procedura memorizzata Suppliers_Select per restituire la colonna calcolata FullContactName e
  2. Aggiornamento di DataTable per includere una colonna corrispondente FullContactName .

Per iniziare, passare a Esplora server ed eseguire il drill-down nella cartella Stored Procedure. Aprire la stored procedure Suppliers_Select e aggiornare l'interrogazione SELECT in modo da includere la colonna calcolata FullContactName.

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

Salvare le modifiche apportate alla stored procedure facendo clic sull'icona Salva sulla barra degli strumenti, premendo CTRL+S o scegliendo l'opzione Salva Suppliers_Select dal menu File.

Tornare quindi a Progettazione set di dati, fare clic con il pulsante destro del mouse su SuppliersTableAdapter e scegliere Configura dal menu di scelta rapida. Si noti che la colonna Suppliers_Select ora include la colonna FullContactName nella raccolta Colonne di dati.

Eseguire la Configurazione guidata TableAdapter per aggiornare le colonne di DataTable

Figura 6: Eseguire la Configurazione guidata TableAdapter per aggiornare le colonne di DataTable (fare clic per visualizzare l'immagine a dimensione intera)

Fare clic su Fine per completare la procedura guidata. In questo modo verrà aggiunta automaticamente una colonna corrispondente all'oggetto SuppliersDataTable. La procedura guidata TableAdapter è sufficientemente intelligente da rilevare che la FullContactName colonna è una colonna calcolata e quindi di sola lettura. Di conseguenza, imposta la proprietà della ReadOnly colonna su true. Per verificarlo, selezionare la colonna da SuppliersDataTable e quindi passare alla Finestra Proprietà (vedere la figura 7). Si noti che anche le proprietà FullContactName, DataType e MaxLength della colonna vengono impostate di conseguenza.

La colonna FullContactName è contrassegnata come di sola lettura

Figura 7: La FullContactName colonna è contrassegnata come Read-Only (fare clic per visualizzare l'immagine a dimensione intera)

Passaggio 5: Aggiunta di unGetSupplierBySupplierIDmetodo a TableAdapter

Per questa esercitazione verrà creata una pagina ASP.NET che visualizza i fornitori in una griglia aggiornabile. Nelle esercitazioni precedenti è stato aggiornato un singolo record dal livello di logica di business recuperando il record specifico dal DAL come DataTable fortemente tipizzato, aggiornandone le proprietà e quindi inviando nuovamente il DataTable aggiornato al DAL per propagare le modifiche al database. Per eseguire questo primo passaggio - ovvero il recupero del record da aggiornare dal DAL - è prima necessario aggiungere un metodo GetSupplierBySupplierID(supplierID) al DAL.

Fare clic con il pulsante destro del mouse su SuppliersTableAdapter nella progettazione del set di dati e scegliere l'opzione Aggiungi query dal menu contestuale. Come abbiamo fatto nel passaggio 3, lascia che la procedura guidata generi una nuova stored procedure per noi selezionando l'opzione Crea nuova stored procedure (consultare la figura 3 per uno screenshot di questo passaggio della procedura guidata). Poiché questo metodo restituirà un record con più colonne, indicare che si vuole usare una query SQL che restituisce le righe e fare clic su Avanti.

Scegliere l'opzione SELECT che restituisce righe

Figura 8: Scegliere l'opzione SELECT che restituisce righe (fare clic per visualizzare l'immagine a dimensione intera)

Il passo successivo ci chiede di specificare la query da usare per questo metodo. Immettere quanto segue, che restituisce gli stessi campi dati della query principale, ma per un determinato fornitore.

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

Nella schermata successiva viene chiesto di assegnare un nome alla stored procedure che verrà generata automaticamente. Assegna un nome a questa stored procedure Suppliers_SelectBySupplierID e fai clic su Avanti.

Assegnare alla stored procedure il nome Suppliers_SelectBySupplierID

Figura 9: Assegnare un nome alla stored procedure Suppliers_SelectBySupplierID (fare clic per visualizzare l'immagine a dimensione intera)

Infine, la procedura guidata richiede i modelli di accesso ai dati e i nomi dei metodi da usare per TableAdapter. Lasciare entrambe le caselle di controllo selezionate, ma rinominare rispettivamente i FillBy metodi e GetDataBy in FillBySupplierID e GetSupplierBySupplierID.

Denominare i metodi TableAdapter FillBySupplierID e GetSupplierBySupplierID

Figura 10: Denominare i metodi FillBySupplierID TableAdapter e GetSupplierBySupplierID (fare clic per visualizzare l'immagine a dimensione intera)

Fare clic su Fine per completare la procedura guidata.

Passaggio 6: Creazione del livello della logica di business

Prima di creare una pagina di ASP.NET che usa la colonna calcolata creata nel passaggio 1, è prima necessario aggiungere i metodi corrispondenti nel BLL. La pagina ASP.NET, che verrà creata nel passaggio 7, consentirà agli utenti di visualizzare e modificare i fornitori. Pertanto, abbiamo bisogno del nostro BLL per fornire, almeno, un metodo per ottenere tutti i fornitori e un altro per aggiornare un determinato fornitore.

Creare un nuovo file di classe denominato SuppliersBLLWithSprocs nella ~/App_Code/BLL cartella e aggiungere il codice seguente:

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

Analogamente alle altre classi BLL, SuppliersBLLWithSprocs ha una proprietà che restituisce un'istanza ProtectedAdapter della SuppliersTableAdapter classe insieme a due Public metodi: GetSuppliers e UpdateSupplier. Il GetSuppliers metodo chiama e restituisce l'oggetto SuppliersDataTable restituito dal metodo corrispondente GetSupplier nel livello di accesso ai dati. Il UpdateSupplier metodo recupera informazioni sul fornitore specifico che viene aggiornato tramite una chiamata al metodo GetSupplierBySupplierID(supplierID) del DAL. Aggiorna quindi le proprietà CategoryName, ContactName e ContactTitle ed esegue il commit di queste modifiche nel database chiamando il metodo del livello di dati del Update, passando l'oggetto modificato SuppliersRow.

Nota

Ad eccezione di SupplierID e CompanyName, tutte le colonne della tabella Suppliers consentono NULL valori. Pertanto, se i parametri contactName o contactTitle passati sono Nothing, dobbiamo impostare le proprietà ContactName e ContactTitle corrispondenti su un valore del database NULL usando rispettivamente i metodi SetContactNameNull e SetContactTitleNull.

Passaggio 7: Utilizzo della colonna calcolata nel livello di presentazione

Con la colonna calcolata aggiunta alla Suppliers tabella e il DAL e BLL aggiornati di conseguenza, è possibile compilare una pagina ASP.NET che funziona con la FullContactName colonna calcolata. Per iniziare, aprire la ComputedColumns.aspx pagina nella AdvancedDAL cartella e trascinare GridView dalla Toolbox sul Designer. Impostare la proprietà GridView su Suppliers e, dallo smart tag, associarla a un nuovo ObjectDataSource denominato SuppliersDataSource. Configurare ObjectDataSource per usare la SuppliersBLLWithSprocs classe aggiunta di nuovo nel passaggio 6 e fare clic su Avanti.

Configurare ObjectDataSource per l'uso della classe SuppliersBLLWithSprocs

Figura 11: Configurare ObjectDataSource per l'uso della classe (SuppliersBLLWithSprocs a dimensione intera)

Nella classe sono definiti SuppliersBLLWithSprocs solo due metodi: GetSuppliers e UpdateSupplier. Assicurarsi che questi due metodi siano specificati rispettivamente nelle schede SELECT e UPDATE e fare clic su Fine per completare la configurazione di ObjectDataSource.

Al termine della procedura guidata di configurazione dell'origine dati, Visual Studio aggiungerà un BoundField per ciascuno dei campi dati restituiti. Rimuovere il BoundField SupplierID e modificare le proprietà di HeaderText, CompanyName, ContactName, ContactTitle e FullContactName rispettivamente a Company, Contact Name, Title e Full Contact Name. Dallo smart tag selezionare la casella di controllo Abilita modifica per attivare le funzionalità di modifica predefinite di GridView.

Oltre ad aggiungere BoundFields alla GridView, il completamento della Creazione guidata dell'origine dati fa sì che Visual Studio imposti la proprietà ObjectDataSource su OldValuesParameterFormatStringoriginal_{0}. Ripristinare il valore predefinito di questa impostazione, {0} .

Dopo aver apportato queste modifiche a GridView e ObjectDataSource, il markup dichiarativo dovrebbe essere simile al seguente:

<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>

Visitare quindi questa pagina tramite un browser. Come illustrato nella figura 12, ogni fornitore è elencato in una griglia che include la FullContactName colonna, il cui valore è semplicemente la concatenazione delle altre tre colonne formattate come ContactName (ContactTitle, CompanyName).

Ogni fornitore è elencato nella griglia

Figura 12: Ogni fornitore è elencato nella griglia (fare clic per visualizzare l'immagine a dimensione intera)

Facendo clic sul pulsante Modifica per un determinato fornitore, viene generato un postback e quella riga viene visualizzata nella sua interfaccia di modifica (vedere la figura 13). Il rendering delle prime tre colonne avviene nell'interfaccia di modifica predefinita: un controllo di tipo TextBox la cui proprietà Text è impostata sul valore del campo dati. La FullContactName colonna rimane tuttavia come testo. Quando i BoundFields sono stati aggiunti a GridView al completamento della procedura guidata di configurazione dell'origine dati, la FullContactName proprietà BoundField è ReadOnly stata impostata su True perché la colonna corrispondente FullContactName in SuppliersDataTable ha la relativa ReadOnly proprietà impostata su True. Come indicato nel passaggio 4, la FullContactName proprietà s ReadOnly è stata impostata su True perché TableAdapter ha rilevato che la colonna era una colonna calcolata.

La colonna FullContactName non è modificabile

Figura 13: La FullContactName colonna non è modificabile (fare clic per visualizzare l'immagine a dimensione intera)

Procedere e aggiornare il valore di una o più colonne modificabili e fare clic su Aggiorna. Si noti che il FullContactName valore di s viene aggiornato automaticamente per riflettere la modifica.

Nota

GridView usa attualmente BoundFields per i campi modificabili, con conseguente interfaccia di modifica predefinita. Poiché il CompanyName campo è obbligatorio, deve essere convertito in un oggetto TemplateField che include requiredFieldValidator. Lascio questo come esercizio per il lettore interessato. Consultare l'esercitazione Aggiunta di controlli di convalida alle interfacce di modifica e inserimento per istruzioni dettagliate sulla conversione di un oggetto BoundField in un oggetto TemplateField e sull'aggiunta di controlli di convalida.

Riepilogo

Quando si definisce lo schema per una tabella, Microsoft SQL Server consente l'inclusione di colonne calcolate. Si tratta di colonne i cui valori vengono calcolati da un'espressione che in genere fa riferimento ai valori di altre colonne nello stesso record. Poiché i valori per le colonne calcolate sono basati su un'espressione, sono di sola lettura e non possono essere assegnati a un valore in un'istruzione INSERT o UPDATE . Ciò presenta problemi quando si utilizza una colonna calcolata nella query principale di un TableAdapter, tentando di generare automaticamente le istruzioni corrispondenti INSERT, UPDATE e DELETE.

In questa esercitazione sono illustrate le tecniche per aggirare le sfide poste dalle colonne calcolate. In particolare, è stata utilizzata una procedura memorizzata nei TableAdapter per superare la fragilità intrinseca degli oggetti TableAdapter che utilizzano istruzioni SQL ad hoc. Quando la procedura guidata TableAdapter crea nuove stored procedure, è importante che la query principale debba inizialmente omettere tutte le colonne calcolate, in quanto la loro presenza impedisce la generazione delle stored procedure per la modifica dei dati. Dopo la configurazione iniziale di TableAdapter, è possibile riorganizzare la SelectCommand stored procedure per includere tutte le colonne calcolate.

Buon programmatori!

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, ha lavorato con le tecnologie Web Microsoft dal 1998. Scott lavora come consulente indipendente, formatore e scrittore. Il suo ultimo libro è Sams Teach Yourself ASP.NET 2.0 in 24 ore. Può essere raggiunto a mitchell@4GuysFromRolla.com.

Grazie speciale a

Questa serie di esercitazioni è stata esaminata da diversi revisori validi. I revisori principali per questa esercitazione erano Hilton Geisenow e Teresa Murphy. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, mandami un messaggio a mitchell@4GuysFromRolla.com.