Esecuzione di query sui dati con il controllo SqlDataSource (VB)

di Scott Mitchell

Scarica il PDF

Nelle esercitazioni precedenti è stato usato il controllo ObjectDataSource per separare completamente il livello di presentazione dal livello di accesso ai dati. A partire da questa esercitazione si apprenderà come usare il controllo SqlDataSource per applicazioni semplici che non richiedono una separazione così rigorosa di presentazione e accesso ai dati.

Introduzione

Tutte le esercitazioni esaminate finora hanno usato un'architettura a livelli costituita da livelli di presentazione, logica di business e accesso ai dati. Il livello di accesso ai dati (DAL) è stato creato nella prima esercitazione (Creazione di un livello di accesso ai dati) e del livello della logica di business nel secondo (Creazione di un livello di logica di business). A partire dall'esercitazione Visualizzazione dei dati con ObjectDataSource , è stato illustrato come usare ASP.NET 2.0 nuovo controllo ObjectDataSource per interfacciarsi in modo dichiarativo con l'architettura dal livello di presentazione.

Anche se tutte le esercitazioni finora hanno usato l'architettura per lavorare con i dati, è anche possibile accedere, inserire, aggiornare ed eliminare i dati del database direttamente da una pagina di ASP.NET, ignorando l'architettura. In questo modo, le query di database e la logica di business specifiche si trovano direttamente nella pagina Web. Per applicazioni sufficientemente grandi o complesse, la progettazione, l'implementazione e l'uso di un'architettura a livelli è fondamentale per il successo, l'updatabilità e la gestibilità dell'applicazione. Lo sviluppo di un'architettura affidabile, tuttavia, potrebbe non essere necessario quando si creano applicazioni estremamente semplici e occasionali.

ASP.NET 2.0 offre cinque controlli origine dati predefiniti SqlDataSource, AccessDataSource, ObjectDataSource, XmlDataSource e SiteMapDataSource. SqlDataSource può essere usato per accedere e modificare i dati direttamente da un database relazionale, tra cui Microsoft SQL Server, Microsoft Access, Oracle, MySQL e altri. In questa esercitazione e nelle tre successive si esaminerà come usare il controllo SqlDataSource, esplorando come eseguire query e filtrare i dati del database, nonché come usare SqlDataSource per inserire, aggiornare ed eliminare dati.

ASP.NET 2.0 include cinque controlli origine dati Built-In

Figura 1: ASP.NET 2.0 include cinque controlli origine dati Built-In

Confronto tra ObjectDataSource e SqlDataSource

Concettualmente, entrambi i controlli ObjectDataSource e SqlDataSource sono semplicemente proxy ai dati. Come descritto nell'esercitazione Visualizzazione dei dati con ObjectDataSource, ObjectDataSource include proprietà che indicano il tipo di oggetto che fornisce i dati e i metodi da richiamare per selezionare, inserire, aggiornare ed eliminare dati dal tipo di oggetto sottostante. Dopo aver configurato le proprietà di ObjectDataSource, è possibile associare al controllo un controllo Web dati, ad esempio GridView, DetailsView o DataList, utilizzando i metodi ObjectDataSource s Select(), Insert(), Delete()e Update() per interagire con l'architettura sottostante.

SqlDataSource offre la stessa funzionalità, ma opera su un database relazionale anziché su una libreria di oggetti. Con SqlDataSource è necessario specificare il stringa di connessione del database e le query SQL ad hoc o le stored procedure da eseguire per inserire, aggiornare, eliminare e recuperare i dati. I metodi , Insert(), Update(), e Delete() di Select()SqlDataSource, quando richiamati, si connettono al database specificato ed eseguono la query SQL appropriata. Come illustrato nel diagramma seguente, questi metodi eseguono il lavoro grunt di connessione a un database, l'emissione di una query e la restituzione dei risultati.

SqlDataSource funge da proxy per il database

Figura 2: SqlDataSource funge da proxy per il database

Nota

In questa esercitazione verrà illustrato come recuperare i dati dal database. Nell'esercitazione Inserimento, aggiornamento ed eliminazione di dati con il controllo SqlDataSource verrà illustrato come configurare SqlDataSource per supportare l'inserimento, l'aggiornamento e l'eliminazione.

Controlli SqlDataSource e AccessDataSource

Oltre al controllo SqlDataSource, ASP.NET 2.0 include anche un controllo AccessDataSource. Questi due controlli diversi consentono a molti sviluppatori di ASP.NET 2.0 di sospettare che il controllo AccessDataSource sia progettato per funzionare esclusivamente con Microsoft Access con il controllo SqlDataSource progettato per funzionare esclusivamente con Microsoft SQL Server. Anche se AccessDataSource è progettato per funzionare in modo specifico con Microsoft Access, il controllo SqlDataSource funziona con qualsiasi database relazionale accessibile tramite .NET. Sono inclusi tutti gli archivi dati conformi a OleDb o ODBC, ad esempio Microsoft SQL Server, Microsoft Access, Oracle, Informix, MySQL e PostgreSQL, tra gli altri.

L'unica differenza tra i controlli AccessDataSource e SqlDataSource è la modalità di specifica delle informazioni di connessione al database. Il controllo AccessDataSource richiede solo il percorso del file di database di Access. SqlDataSource, invece, richiede un stringa di connessione completo.

Passaggio 1: Creazione delle pagine Web SqlDataSource

Prima di iniziare a esplorare come usare direttamente i dati del database usando il controllo SqlDataSource, è necessario prima di tutto creare le pagine ASP.NET nel progetto del sito Web necessarie per questa esercitazione e le tre successive. Per iniziare, aggiungere una nuova cartella denominata SqlDataSource. Aggiungere quindi le pagine di ASP.NET seguenti a tale cartella, assicurandosi di associare ogni pagina alla Site.master pagina master:

  • Default.aspx
  • Querying.aspx
  • ParameterizedQueries.aspx
  • InsertUpdateDelete.aspx
  • OptimisticConcurrency.aspx

Aggiungere le pagine ASP.NET per le esercitazioni SqlDataSource-Related

Figura 3: Aggiungere le pagine di ASP.NET per le esercitazioni SqlDataSource-Related

Come nelle altre cartelle, Default.aspx nella SqlDataSource cartella verranno elencate le esercitazioni nella relativa sezione. Tenere presente che il SectionLevelTutorialListing.ascx controllo utente fornisce questa funzionalità. Aggiungere quindi questo controllo utente a Default.aspx trascinandolo dal Esplora soluzioni nella visualizzazione Struttura della pagina.

Aggiungere il controllo utente SectionLevelTutorialListing.ascx a Default.aspx

Figura 4: Aggiungere il SectionLevelTutorialListing.ascx controllo utente a Default.aspx (fare clic per visualizzare l'immagine a dimensione intera)

Infine, aggiungere queste quattro pagine come voci al Web.sitemap file. In particolare, aggiungere il markup seguente dopo l'aggiunta di pulsanti personalizzati a DataList e Repeater <siteMapNode>:

<siteMapNode url="~/SqlDataSource/Default.aspx"
    title="Using the SqlDataSource Control"
    description="Work directly with database data using the SqlDataSource control.">
    <siteMapNode url="~/SqlDataSource/Querying.aspx" title="Retrieving Database Data"
        description="Examines how to query data from a database that can then be
                     displayed  through a data Web control."/>
    <siteMapNode url="~/SqlDataSource/ParameterizedQueries.aspx"
        title="Parameterized Queries"
        description="Learn how to specify parameterized WHERE clauses in the
                     SqlDataSource's SELECT statement." />
    <siteMapNode url="~/SqlDataSource/InsertUpdateDelete.aspx"
        title="Inserting, Updating, and Deleting Database Data"
        description="See how to configure the SqlDataSource to include INSERT, UPDATE,
                      and DELETE statements." />
    <siteMapNode url="~/SqlDataSource/OptimisticConcurrency.aspx"
        title="Using Optimistic Concurrency"
        description="Explore how to augment the SqlDataSource to include support for
                     optimistic concurrency." />
</siteMapNode>

Dopo l'aggiornamento Web.sitemap, dedicare qualche minuto alla visualizzazione del sito Web delle esercitazioni tramite un browser. Il menu a sinistra include ora elementi per le esercitazioni di modifica, inserimento ed eliminazione.

La mappa del sito include ora voci per le esercitazioni su SqlDataSource

Figura 5: La mappa del sito include ora voci per le esercitazioni su SqlDataSource

Passaggio 2: Aggiunta e configurazione del controllo SqlDataSource

Per iniziare, aprire la Querying.aspx pagina nella SqlDataSource cartella e passare alla visualizzazione Struttura. Trascinare un controllo SqlDataSource dalla casella degli strumenti nel Designer e impostarlo ID su ProductsDataSource. Come per ObjectDataSource, SqlDataSource non produce alcun output di cui è stato eseguito il rendering e pertanto viene visualizzato come una casella grigia nell'area di progettazione. Per configurare SqlDataSource, fare clic sul collegamento Configura origine dati dallo smart tag sqlDataSource.

Fare clic sul Source Link Configura dati dallo smart tag sqlDataSource

Figura 6: Fare clic sul Source Link Configura dati dallo smart tag sqlDataSource

Verrà visualizzata la procedura guidata Configura origine dati del controllo SqlDataSource. Sebbene i passaggi della procedura guidata differiscano dal controllo ObjectDataSource, l'obiettivo finale è lo stesso per fornire i dettagli su come recuperare, inserire, aggiornare ed eliminare dati tramite l'origine dati. Per SqlDataSource questo comporta la specifica del database sottostante da usare e la fornitura di istruzioni SQL ad hoc o stored procedure.

Il primo passaggio della procedura guidata richiede il database. L'elenco a discesa include i database presenti nella cartella dell'applicazione App_Data Web e quelli aggiunti al nodo Data Connections in Esplora server. Poiché è già stato aggiunto un stringa di connessione per il NORTHWIND.MDF database nella App_Data cartella al file del Web.config progetto, l'elenco a discesa include un riferimento a tale stringa di connessione, NORTHWINDConnectionString. Scegliere questo elemento dall'elenco a discesa e fare clic su Avanti.

Scegliere NORTHWINDConnectionString dall'elenco Drop-Down

Figura 7: Scegliere dall'elenco NORTHWINDConnectionString Drop-Down

Dopo aver scelto il database, la procedura guidata richiede che la query restituisca i dati. È possibile specificare le colonne di una tabella o di una vista da restituire oppure immettere un'istruzione SQL personalizzata o specificare una stored procedure. È possibile alternare questa opzione tramite specificare un'istruzione SQL personalizzata o una stored procedure e specificare le colonne da una tabella o visualizzare pulsanti di opzione.

Nota

Per questo primo esempio, è possibile usare l'opzione Specifica colonne da una tabella o da una vista. Tornare alla procedura guidata più avanti in questa esercitazione ed esplorare l'opzione Specificare un'istruzione SQL personalizzata o una stored procedure.

La figura 8 mostra la schermata Configura istruzione seleziona quando è selezionato il pulsante di opzione Specifica colonne da una tabella o vista. L'elenco a discesa contiene il set di tabelle e viste nel database Northwind, con le colonne della tabella o della vista selezionate visualizzate nell'elenco di caselle di controllo riportato di seguito. Per questo esempio, è possibile restituire le ProductIDcolonne , ProductNamee UnitPrice dalla Products tabella . Come illustrato nella figura 8, dopo aver eseguito queste selezioni, la procedura guidata mostra l'istruzione SELECT [ProductID], [ProductName], [UnitPrice] FROM [Products]SQL risultante.

Restituire dati dalla tabella Products

Figura 8: Restituire dati dalla Products tabella

Dopo aver configurato la procedura guidata per restituire le ProductIDcolonne , ProductNamee UnitPrice dalla Products tabella, fare clic sul pulsante Avanti. Questa schermata finale offre l'opportunità di esaminare i risultati della query configurata nel passaggio precedente. Facendo clic sul pulsante Query di test viene eseguita l'istruzione configurata SELECT e vengono visualizzati i risultati in una griglia.

Fare clic sul pulsante Query di test per esaminare la query SELECT

Figura 9: Fare clic sul pulsante Query di test per esaminare la SELECT query

Per completare la procedura guidata, fare clic su Fine.

Analogamente a ObjectDataSource, la procedura guidata di SqlDataSource assegna semplicemente valori alle proprietà del controllo, ovvero le ConnectionString proprietà e SelectCommand . Al termine della procedura guidata, il markup dichiarativo del controllo SqlDataSource dovrebbe essere simile al seguente:

<asp:SqlDataSource ID="ProductsDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand="SELECT [ProductID], [ProductName], [UnitPrice] FROM [Products]">
</asp:SqlDataSource>

La ConnectionString proprietà fornisce informazioni su come connettersi al database. A questa proprietà può essere assegnato un valore completo hardcoded stringa di connessione o può puntare a un stringa di connessione in Web.config. Per fare riferimento a un valore di stringa di connessione in Web.config, usare la sintassi <%$ expressionPrefix:expressionValue %>. In genere expressionPrefix è ConnectionStrings ed expressionValue è il nome della stringa di connessione nella Web.config<connectionStrings> sezione. Tuttavia, la sintassi può essere usata per fare riferimento <appSettings> a elementi o contenuto da file di risorse. Per altre informazioni su questa sintassi, vedere panoramica delle espressioni di ASP.NET .

La SelectCommand proprietà specifica l'istruzione SQL ad hoc o la stored procedure da eseguire per restituire i dati.

Passaggio 3: Aggiungere un controllo Web dati e associarlo a SqlDataSource

Dopo aver configurato SqlDataSource, può essere associato a un controllo Web dati, ad esempio GridView o DetailsView. Per questa esercitazione, è possibile visualizzare i dati in un controllo GridView. Dalla casella degli strumenti trascinare un controllo GridView nella pagina e associarlo a ProductsDataSource SqlDataSource scegliendo l'origine dati dall'elenco a discesa nello smart tag di GridView.

Aggiungere un controllo GridView e associarlo al controllo SqlDataSource

Figura 10: Aggiungere un controllo GridView e associarlo al controllo SqlDataSource (fare clic per visualizzare l'immagine a dimensione intera)

Dopo aver selezionato il controllo SqlDataSource dall'elenco a discesa nello smart tag di GridView, Visual Studio aggiungerà automaticamente un BoundField o CheckBoxField a GridView per ognuna delle colonne restituite dal controllo origine dati. Poiché SqlDataSource restituisce tre colonne ProductIDdi database , ProductNamee UnitPrice sono presenti tre campi in GridView.

Dedicare qualche minuto alla configurazione dei tre BoundFields di GridView. Modificare la ProductName proprietà del HeaderText campo in Product Name (Nome prodotto) e il UnitPrice campo s su Price (Prezzo). Formattare anche il UnitPrice campo come valuta. Dopo aver apportato queste modifiche, il markup dichiarativo di GridView dovrebbe essere simile al seguente:

<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ProductsDataSource"
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductID" HeaderText="ProductID"
            InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName" HeaderText="Product Name"
            SortExpression="ProductName" />
        <asp:BoundField DataField="UnitPrice" HeaderText="Price"
            SortExpression="UnitPrice" DataFormatString="{0:c}"
            HtmlEncode="False" />
    </Columns>
</asp:GridView>

Visitare questa pagina tramite un browser. Come illustrato nella figura 11, GridView elenca i valori , ProductNamee UnitPrice di ProductIDogni prodotto.

GridView visualizza i valori ProductID, ProductName e UnitPrice di ogni prodotto

Figura 11: GridView visualizza ogni prodotto , ProductIDProductNamee UnitPrice valori (fare clic per visualizzare l'immagine a dimensione intera)

Quando la pagina viene visitata, GridView richiama il relativo metodo del Select() controllo origine dati. Quando si usava il controllo ObjectDataSource, questo metodo ha chiamato il ProductsBLL metodo della GetProducts() classe . Con SqlDataSource, tuttavia, il Select() metodo stabilisce una connessione al database specificato e rilascia (SelectCommandSELECT [ProductID], [ProductName], [UnitPrice] FROM [Products]in questo esempio). SqlDataSource restituisce i risultati che GridView enumera, creando una riga in GridView per ogni record di database restituito.

Funzionalità del controllo Web dei dati Built-In e del controllo SqlDataSource

In generale, le funzionalità inerenti al paging dei controlli Web dati, l'ordinamento, la modifica, l'eliminazione, l'inserimento e così via sono specifiche per il controllo Web dei dati e non dipendono dal controllo origine dati utilizzato. Ovvero, GridView può utilizzare il paging predefinito, l'ordinamento, la modifica e l'eliminazione se è associato a objectDataSource o a sqlDataSource. Tuttavia, alcune funzionalità di controllo Web dati sono sensibili al controllo origine dati in uso o alla configurazione del controllo origine dati.

Ad esempio, nell'esercitazione Sul paging efficiente di grandi quantità di dati è stato illustrato come, per impostazione predefinita, la logica di paging per i controlli Web dati restituisce in modo ingenuo tutti i record dall'origine dati sottostante e quindi visualizza solo il subset appropriato di record in base all'indice di pagina corrente e al numero di record da visualizzare per pagina. Questo modello è estremamente inefficiente quando si esegue il paging in set di risultati sufficientemente grandi. Fortunatamente, ObjectDataSource può essere configurato per supportare il paging personalizzato, che restituisce solo il subset preciso di record da visualizzare. Il controllo SqlDataSource, tuttavia, non dispone delle proprietà per l'implementazione del paging personalizzato.

Un'altra sottilezza con il paging e l'ordinamento si verifica con SqlDataSource. Per impostazione predefinita, i dati restituiti da sqlDataSource possono essere sottoposti a paging o ordinati tramite GridView. Per dimostrare questo problema, controllare le opzioni Abilita paging e Abilita ordinamento nello smart tag gridView in Querying.aspx e verificare che funzioni come previsto.

L'ordinamento e il paging funzionano perché SqlDataSource recupera i dati del database in un dataset di tipo libero. Il numero totale di record restituiti dalla query è un aspetto essenziale per implementare il paging da DataSet. Inoltre, i risultati del set di dati possono essere ordinati tramite un oggetto DataView. Queste funzionalità vengono usate automaticamente da SqlDataSource quando GridView richiede dati di paging o ordinati.

SqlDataSource può essere configurato per restituire un Oggetto DataReader anziché un Oggetto DataSet modificandone DataSourceMode la proprietà da DataSet (impostazione predefinita) a DataReader. L'uso di un DataReader può essere preferibile in situazioni in cui si passano i risultati di SqlDataSource al codice esistente che prevede un DataReader. Inoltre, poiché i DataReader sono oggetti notevolmente più semplici rispetto ai DataSet, offrono prestazioni migliori. Se si apporta questa modifica, tuttavia, il controllo Web dei dati non può né ordinare né pagina poiché SqlDataSource non è in grado di verificare il numero di record restituiti dalla query, né DataReader offre alcuna tecnica per l'ordinamento dei dati restituiti.

Passaggio 4: Uso di un'istruzione SQL personalizzata o di una stored procedure

Quando si configura il controllo SqlDataSource, la query usata per restituire dati può essere specificata in uno dei due approcci come istruzione SQL personalizzata o stored procedure oppure come colonne di una tabella o vista esistente. Nel passaggio 2 è stata esaminata la selezione delle colonne dalla Products tabella. Si esamini ora l'uso di un'istruzione SQL personalizzata.

Aggiungere un altro controllo GridView alla Querying.aspx pagina e scegliere di creare una nuova origine dati dall'elenco a discesa nello smart tag. Indicare quindi che i dati verranno estratti da un database che creerà un nuovo controllo SqlDataSource. Assegnare al controllo ProductsWithCategoryInfoDataSourceil nome .

Creare un nuovo controllo SqlDataSource denominato ProductsWithCategoryInfoDataSource

Figura 12: Creare un nuovo controllo SqlDataSource denominato ProductsWithCategoryInfoDataSource

Nella schermata successiva viene chiesto di specificare il database. Come è stato fatto nella figura 7, selezionare dall'elenco NORTHWINDConnectionString a discesa e fare clic su Avanti. Nella schermata Configura istruzione Select scegliere il pulsante di opzione Specificare un'istruzione SQL personalizzata o una stored procedure e fare clic su Avanti. Verrà visualizzata la schermata Definisci istruzioni personalizzate o stored procedure, che offre schede con etichetta SELECT, UPDATE, INSERT e DELETE. In ogni scheda è possibile immettere un'istruzione SQL personalizzata nella casella di testo o scegliere una stored procedure dall'elenco a discesa. In questa esercitazione verrà esaminata l'immissione di un'istruzione SQL personalizzata. L'esercitazione successiva include un esempio che usa una stored procedure.

Immettere un'istruzione SQL personalizzata o selezionare una stored procedure

Figura 13: Immettere un'istruzione SQL personalizzata o selezionare una stored procedure

L'istruzione SQL personalizzata può essere immessa manualmente nella casella di testo o può essere costruita graficamente facendo clic sul pulsante Generatore query. Nella casella di testo Generatore query o nella casella di testo usare la query seguente per restituire i ProductID campi e ProductName dalla Products tabella usando un JOIN oggetto per recuperare il prodotto CategoryName dalla Categories tabella:

SELECT Products.ProductID, Products.ProductName, Categories.CategoryName
FROM Categories
    INNER JOIN Products ON
        Categories.CategoryID = Products.CategoryID

È possibile costruire graficamente la query usando Generatore query

Figura 14: È possibile costruire graficamente la query usando Generatore query

Dopo aver specificato la query, fare clic su Avanti per passare alla schermata Query di test. Fare clic su Fine per completare la procedura guidata SqlDataSource.

Al termine della procedura guidata, GridView avrà tre BoundFields aggiunti visualizzando le ProductIDcolonne , ProductNamee CategoryName restituite dalla query e con il markup dichiarativo seguente:

<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
    DataKeyNames="ProductID" DataSourceID="ProductsWithCategoryInfoDataSource"
    EnableViewState="False">
    <Columns>
        <asp:BoundField DataField="ProductID" HeaderText="ProductID"
            InsertVisible="False" ReadOnly="True" SortExpression="ProductID" />
        <asp:BoundField DataField="ProductName" HeaderText="ProductName"
            SortExpression="ProductName" />
        <asp:BoundField DataField="CategoryName" HeaderText="CategoryName"
            SortExpression="CategoryName" />
    </Columns>
</asp:GridView>
<asp:SqlDataSource ID="ProductsWithCategoryInfoDataSource" runat="server"
    ConnectionString="<%$ ConnectionStrings:NORTHWNDConnectionString %>"
    SelectCommand="
        SELECT Products.ProductID, Products.ProductName, Categories.CategoryName
        FROM Categories
        INNER JOIN Products ON Categories.CategoryID = Products.CategoryID">
</asp:SqlDataSource>

GridView mostra ogni ID prodotto, nome e nome di categoria associato

Figura 15: GridView mostra ogni ID prodotto, nome e nome della categoria associata (fare clic per visualizzare l'immagine a dimensione intera)

Riepilogo

In questa esercitazione è stato illustrato come eseguire query e visualizzare i dati usando il controllo SqlDataSource. Analogamente a ObjectDataSource, SqlDataSource funge da proxy, fornendo un approccio dichiarativo per l'accesso ai dati. Le relative proprietà specificano il database a cui connettersi e la query SQL SELECT da eseguire; possono essere specificate tramite il Finestra Proprietà o tramite la procedura guidata Configura origine dati.

Negli SELECT esempi di query esaminati in questa esercitazione sono stati restituiti tutti i record dalla query specificata. Il controllo SqlDataSource, tuttavia, può includere una WHERE clausola con parametri i cui valori vengono assegnati a livello di codice o vengono automaticamente estratti da un'origine specificata. Si esaminerà come creare e usare query con parametri nell'esercitazione successiva.

Buon programmatori!

Altre informazioni

Per altre informazioni sugli argomenti descritti in questa esercitazione, vedere le risorse seguenti:

Informazioni sull'autore

Scott Mitchell, autore di sette libri ASP/ASP.NET e fondatore di 4GuysFromRolla.com, lavora 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 all'indirizzo mitchell@4GuysFromRolla.com. o tramite il suo blog, disponibile all'indirizzo http://ScottOnWriting.NET.

Grazie speciale a

Questa serie di esercitazioni è stata esaminata da molti revisori utili. I revisori principali di questa esercitazione sono Stati Susan Connery, Bernadette Leigh e David Suru. Si è interessati a esaminare i prossimi articoli MSDN? In tal caso, rilasciami una riga in mitchell@4GuysFromRolla.com.