Progettare un database SQL di Azure e connettersi con C# e ADO.NET

Il database SQL di Azure è un database relazionale come servizio (DBaaS, Database-As-A-Service) disponibile in Microsoft Cloud ("Azure"). In questa esercitazione viene illustrato come usare il portale di Azure e ADO.NET con Visual Studio per eseguire queste operazioni:

  • Creare un database nel portale di Azure
  • Impostare una regola del firewall a livello di server nel portale di Azure
  • Connettersi al database con ADO.NET e Visual Studio
  • Creare tabelle con ADO.NET
  • Inserire, aggiornare ed eliminare dati con ADO.NET
  • Eseguire query sui dati con ADO.NET

Se non si ha una sottoscrizione di Azure, creare un account gratuito prima di iniziare.

Prerequisiti

Un'installazione di Visual Studio Community 2017, Visual Studio Professional 2017 o Visual Studio Enterprise 2017.

Accedere al Portale di Azure.

Accedere al Portale di Azure.

Creare un database SQL vuoto usando il portale di Azure

Un database SQL di Azure viene creato con un set definito di risorse di calcolo e di archiviazione. Il database viene creato in un gruppo di risorse di Azure e in un server logico di database SQL di Azure.

Per creare un database SQL vuoto, attenersi alla procedura seguente.

  1. Fare clic sul pulsante Nuovo nell'angolo superiore sinistro del portale di Azure.

  2. Selezionare Database nella pagina Nuovo e quindi Database SQL nella pagina Database.

    creare database vuoto

  3. Compilare il modulo Database SQL con le informazioni seguenti, come illustrato nell'immagine precedente:

    Impostazione Valore consigliato Descrizione
    Database name (Nome database) mySampleDatabase Per i nomi di database validi, vedere Database Identifiers (Identificatori di database).
    Sottoscrizione Sottoscrizione in uso Per informazioni dettagliate sulle sottoscrizioni, vedere Subscriptions (Sottoscrizioni).
    Gruppo di risorse myResourceGroup Per i nomi di gruppi di risorse validi, vedere Naming rules and restrictions (Regole di denominazione e restrizioni).
    Select source (Seleziona origine) Database vuoto Indica che deve essere creato un database vuoto.
  4. Fare clic su Server per creare e configurare un nuovo server per il nuovo database. Compilare il modulo del nuovo server con le informazioni seguenti:

    Impostazione Valore consigliato Descrizione
    Server name (Nome server) Qualsiasi nome univoco globale. Per i nomi di server validi, vedere Naming rules and restrictions (Regole di denominazione e restrizioni).
    Nome di accesso amministratore server Qualsiasi nome valido. Per i nomi di accesso validi, vedere Database Identifiers (Identificatori di database).
    Password Qualsiasi password valida. La password deve contenere almeno otto caratteri delle tre categorie seguenti: maiuscole, minuscole, numeri e caratteri non alfanumerici.
    Posizione Qualsiasi posizione valida. Per informazioni sulle aree, vedere Aree di Azure.

    Creare il server di database

  5. Fare clic su Seleziona.

  6. Fare clic su Piano tariffario per specificare il livello di servizio e il livello delle prestazioni per il nuovo database. Per esercitazione selezionare 20 DTU e 250 GB di memoria.

    Creare il database s1

  7. Fare clic su Apply.

  8. Selezionare regole di confronto per il database vuoto. Per questa esercitazione usare il valore predefinito. Per altre informazioni sulle regole di confronto, vedere Collations (Regole di confronto)

  9. Fare clic su Crea per effettuare il provisioning del database. Il provisioning richiede circa un minuto e mezzo per il completamento.

  10. Sulla barra degli strumenti fare clic su Notifiche per monitorare il processo di distribuzione.

    notifica

Creare una regola del firewall a livello di server con il portale di Azure

Il servizio di database SQL crea un firewall a livello di server. Inizialmente il firewall impedisce a strumenti esterni e applicazioni di connettersi al server o ai database nel server. Le connessioni sono consentite dopo aver creato una regola del firewall per aprire indirizzi IP specifici. Seguire questi passaggi per creare una regola del firewall a livello di server di database SQL per l'indirizzo IP del client e per abilitare la connettività esterna tramite il firewall del database SQL solo per il proprio indirizzo IP.

Nota

Il database SQL di Azure comunica sulla porta 1433. È possibile connettersi al database SQL solo quando il firewall della rete consente il traffico in uscita attraverso la porta 1433.

  1. Al termine della distribuzione, scegliere Database SQL dal menu a sinistra e fare clic su mySampleDatabase nella pagina Database SQL. Si apre la pagina di panoramica per il database, in cui è indicato il nome completo del server (ad esempio, mynewserver20170313.database.windows.net) e in cui sono disponibili altre opzioni di configurazione. Copiare il nome completo del server per usarlo in seguito.

    Importante

    Questo nome completo del server è necessario per connettersi al server e ai relativi database nelle guide introduttive successive.

    Nome del server

  2. Fare clic su Imposta firewall server sulla barra degli strumenti, come illustrato nell'immagine precedente. Si apre la pagina Impostazioni del firewall per il server del database SQL.

    Regola del firewall del server

  3. Fare clic su Aggiungi IP client sulla barra degli strumenti per aggiungere l'indirizzo IP corrente a una nuova regola del firewall. Una regola del firewall può aprire la porta 1433 per un indirizzo IP singolo o un intervallo di indirizzi IP.

  4. Fare clic su Salva. Viene creata una regola del firewall a livello di server per l'indirizzo IP corrente, che apre la porta 1433 nel server logico.

    Impostare la regola del firewall del server

  5. Fare clic su OK e quindi chiudere la pagina Impostazioni del firewall.

È ora possibile connettersi al server di database SQL di Azure e ai suoi database usando uno strumento come SQL Server Management Studio (SSMS). La connessione viene eseguita da questo indirizzo IP e usa l'account amministratore del server creato in precedenza.

Importante

Per impostazione predefinita, l'accesso attraverso il firewall del database SQL è abilitato per tutti i servizi di Azure. Selezionando NO in questa pagina permette di disabilitare tutti i servizi di Azure.

Ottenere i valori della stringa di connessione usando il portale di Azure

Ottenere il nome completo del server per il server del database SQL di Azure nel portale di Azure. Usare il nome completo del server per connettersi al server tramite SQL Server Management Studio.

  1. Accedere al Portale di Azure.

  2. Scegliere Database SQL dal menu a sinistra, quindi fare clic sul database nella pagina Database SQL.

  3. Nel riquadro Informazioni di base della pagina del portale di Azure per il database individuare e quindi copiare il Nome server.

    informazioni di connessione

Esempio di programma C#

Le sezioni successive di questo articolo presentano un programma C# che usa ADO.NET per inviare istruzioni Transact-SQL al database SQL. Il programma C# esegue le azioni seguenti:

  1. Connessione al database SQL tramite ADO.NET.
  2. Creazione di tabelle.
  3. Popolamento delle tabelle con dati, tramite l'emissione di istruzioni T-SQL INSERT.
  4. Aggiornamento dei dati tramite un join.
  5. Eliminazione dei dati tramite un join.
  6. Selezione di righe di dati tramite join.
  7. Chiusura della connessione, con rilascio di eventuali tabelle temporanee da tempdb.

Il programma C# contiene:

  • Codice C# per la connessione al database.
  • Metodi che restituiscono il codice sorgente di T-SQL.
  • Due metodi che inviano il codice T-SQL al database.

Per la compilazione e l'esecuzione

Questo programma C# è costituito logicamente da un file con estensione cs. In questo caso il programma è suddiviso fisicamente in diversi blocchi di codice, in modo da semplificare la visualizzazione e la comprensione di ogni blocco. Per compilare ed eseguire questo programma, seguire questa procedura:

  1. Creare un progetto C# in Visual Studio.
    • Il tipo di progetto deve essere un'applicazione console, da un elemento simile alla gerarchia seguente: Modelli > Visual C# > Desktop classico di Windows > App console (.NET Framework).
  2. Nel file Program.cs cancellare le brevi righe iniziali del codice.
  3. In Program.cs copiare e incollare ogni blocco seguente nella stessa sequenza riportata.
  4. In Program.cs modificare i valori seguenti nel metodo Main:

    • cb.DataSource
    • cd.UserID
    • cb.Password
    • InitialCatalog
  5. Verificare che sia presente un riferimento all'assembly System.Data.dll. Per la verifica, espandere il nodo Riferimenti nel riquadro Esplora soluzioni.

  6. Per compilare il programma in Visual Studio, fare clic sul menu Compila.
  7. Per eseguire il programma da Visual Studio, fare clic sul pulsante Start. L'output del report viene visualizzato in una finestra di cmd.exe.
Nota

È possibile modificare il codice T-SQL per aggiungere un carattere # davanti ai nomi di tabella, in modo da crearle come tabelle temporanee in tempdb. Ciò può risultare utile per finalità dimostrative, quando non sono disponibili database di test. Le tabelle temporanee vengono eliminate automaticamente alla chiusura della connessione. Eventuali parole chiave REFERENCES per chiavi esterne non vengono applicate per le tabelle temporanee.

Blocco C# 1: Connessione tramite ADO.NET

using System;
using System.Data.SqlClient;   // System.Data.dll 
//using System.Data;           // For:  SqlDbType , ParameterDirection

namespace csharp_db_test
{
   class Program
   {
      static void Main(string[] args)
      {
         try
         {
            var cb = new SqlConnectionStringBuilder();
            cb.DataSource = "your_server.database.windows.net";
            cb.UserID = "your_user";
            cb.Password = "your_password";
            cb.InitialCatalog = "your_database";

            using (var connection = new SqlConnection(cb.ConnectionString))
            {
               connection.Open();

               Submit_Tsql_NonQuery(connection, "2 - Create-Tables",
                  Build_2_Tsql_CreateTables());

               Submit_Tsql_NonQuery(connection, "3 - Inserts",
                  Build_3_Tsql_Inserts());

               Submit_Tsql_NonQuery(connection, "4 - Update-Join",
                  Build_4_Tsql_UpdateJoin(),
                  "@csharpParmDepartmentName", "Accounting");

               Submit_Tsql_NonQuery(connection, "5 - Delete-Join",
                  Build_5_Tsql_DeleteJoin(),
                  "@csharpParmDepartmentName", "Legal");

               Submit_6_Tsql_SelectEmployees(connection);
            }
         }
         catch (SqlException e)
         {
            Console.WriteLine(e.ToString());
         }
         Console.WriteLine("View the report output here, then press any key to end the program...");
         Console.ReadKey();
      }

Blocco C# 2: T-SQL per la creazione di tabelle

      static string Build_2_Tsql_CreateTables()
      {
         return @"
DROP TABLE IF EXISTS tabEmployee;
DROP TABLE IF EXISTS tabDepartment;  -- Drop parent table last.


CREATE TABLE tabDepartment
(
   DepartmentCode  nchar(4)          not null
      PRIMARY KEY,
   DepartmentName  nvarchar(128)     not null
);

CREATE TABLE tabEmployee
(
   EmployeeGuid    uniqueIdentifier  not null  default NewId()
      PRIMARY KEY,
   EmployeeName    nvarchar(128)     not null,
   EmployeeLevel   int               not null,
   DepartmentCode  nchar(4)              null
      REFERENCES tabDepartment (DepartmentCode)  -- (REFERENCES would be disallowed on temporary tables.)
);
";
      }

Diagramma entità-relazione

Le istruzioni CREATE TABLE precedenti usano la parola chiave REFERENCES per creare una relazione chiavi esterne tra le due tabelle. Se si usa tempdb, impostare come commento la parola chiave --REFERENCES usando una coppia di trattini iniziali.

Il diagramma entità-relazione mostra la relazione tra le due tabelle. I valori nella colonna #tabEmployee.DepartmentCode figlio sono limitati ai valori presenti nella colonna #tabDepartment.Department padre.

Diagramma entità-relazione che mostra una chiave esterna

Blocco C# 3: T-SQL per l'inserimento di dati

      static string Build_3_Tsql_Inserts()
      {
         return @"
-- The company has these departments.
INSERT INTO tabDepartment
   (DepartmentCode, DepartmentName)
      VALUES
   ('acct', 'Accounting'),
   ('hres', 'Human Resources'),
   ('legl', 'Legal');

-- The company has these employees, each in one department.
INSERT INTO tabEmployee
   (EmployeeName, EmployeeLevel, DepartmentCode)
      VALUES
   ('Alison'  , 19, 'acct'),
   ('Barbara' , 17, 'hres'),
   ('Carol'   , 21, 'acct'),
   ('Deborah' , 24, 'legl'),
   ('Elle'    , 15, null);
";
      }

Blocco C# 4: T-SQL per l'aggiornamento tramite join

      static string Build_4_Tsql_UpdateJoin()
      {
         return @"
DECLARE @DName1  nvarchar(128) = @csharpParmDepartmentName;  --'Accounting';


-- Promote everyone in one department (see @parm...).
UPDATE empl
   SET
      empl.EmployeeLevel += 1
   FROM
      tabEmployee   as empl
      INNER JOIN
      tabDepartment as dept ON dept.DepartmentCode = empl.DepartmentCode
   WHERE
      dept.DepartmentName = @DName1;
";
      }

Blocco C# 5: T-SQL per l'eliminazione tramite join

      static string Build_5_Tsql_DeleteJoin()
      {
         return @"
DECLARE @DName2  nvarchar(128);
SET @DName2 = @csharpParmDepartmentName;  --'Legal';


-- Right size the Legal department.
DELETE empl
   FROM
      tabEmployee   as empl
      INNER JOIN
      tabDepartment as dept ON dept.DepartmentCode = empl.DepartmentCode
   WHERE
      dept.DepartmentName = @DName2

-- Disband the Legal department.
DELETE tabDepartment
   WHERE DepartmentName = @DName2;
";
      }

Blocco C# 6: T-SQL per la selezione di righe

      static string Build_6_Tsql_SelectEmployees()
      {
         return @"
-- Look at all the final Employees.
SELECT
      empl.EmployeeGuid,
      empl.EmployeeName,
      empl.EmployeeLevel,
      empl.DepartmentCode,
      dept.DepartmentName
   FROM
      tabEmployee   as empl
      LEFT OUTER JOIN
      tabDepartment as dept ON dept.DepartmentCode = empl.DepartmentCode
   ORDER BY
      EmployeeName;
";
      }

Blocco C# 6b: ExecuteReader

Questo metodo è progettato per l'esecuzione dell'istruzione T-SQL SELECT compilata dal metodo Build_6_Tsql_SelectEmployees.

      static void Submit_6_Tsql_SelectEmployees(SqlConnection connection)
      {
         Console.WriteLine();
         Console.WriteLine("=================================");
         Console.WriteLine("Now, SelectEmployees (6)...");

         string tsql = Build_6_Tsql_SelectEmployees();

         using (var command = new SqlCommand(tsql, connection))
         {
            using (SqlDataReader reader = command.ExecuteReader())
            {
               while (reader.Read())
               {
                  Console.WriteLine("{0} , {1} , {2} , {3} , {4}",
                     reader.GetGuid(0),
                     reader.GetString(1),
                     reader.GetInt32(2),
                     (reader.IsDBNull(3)) ? "NULL" : reader.GetString(3),
                     (reader.IsDBNull(4)) ? "NULL" : reader.GetString(4));
               }
            }
         }
      }

Blocco C# 7: ExecuteNonQuery

Questo metodo viene chiamato per operazioni che modificano il contenuto dei dati delle tabelle senza restituire alcuna riga di dati.

      static void Submit_Tsql_NonQuery(
         SqlConnection connection,
         string tsqlPurpose,
         string tsqlSourceCode,
         string parameterName = null,
         string parameterValue = null
         )
      {
         Console.WriteLine();
         Console.WriteLine("=================================");
         Console.WriteLine("T-SQL to {0}...", tsqlPurpose);

         using (var command = new SqlCommand(tsqlSourceCode, connection))
         {
            if (parameterName != null)
            {
               command.Parameters.AddWithValue(  // Or, use SqlParameter class.
                  parameterName,
                  parameterValue);
            }
            int rowsAffected = command.ExecuteNonQuery();
            Console.WriteLine(rowsAffected + " = rows affected.");
         }
      }
   } // EndOfClass
}

Blocco C# 8: Output del test effettivo nella console

Questa sezione acquisisce l'output inviato dal programma alla console. Solo i valori GUID variano tra le esecuzioni dei test.

[C:\csharp_db_test\csharp_db_test\bin\Debug\]
>> csharp_db_test.exe

=================================
Now, CreateTables (10)...

=================================
Now, Inserts (20)...

=================================
Now, UpdateJoin (30)...
2 rows affected, by UpdateJoin.

=================================
Now, DeleteJoin (40)...

=================================
Now, SelectEmployees (50)...
0199be49-a2ed-4e35-94b7-e936acf1cd75 , Alison , 20 , acct , Accounting
f0d3d147-64cf-4420-b9f9-76e6e0a32567 , Barbara , 17 , hres , Human Resources
cf4caede-e237-42d2-b61d-72114c7e3afa , Carol , 22 , acct , Accounting
cdde7727-bcfd-4f72-a665-87199c415f8b , Elle , 15 , NULL , NULL

[C:\csharp_db_test\csharp_db_test\bin\Debug\]
>>

Passaggi successivi

Questa esercitazione ha illustrato le attività di base che è possibile eseguire con i database, come creare database e tabelle, caricare dati, eseguire query sui dati e ripristinare un database a un momento precedente. Si è appreso come:

  • Creare un database
  • Configurare una regola del firewall
  • Connettersi al database con Visual Studio e C#
  • Creare tabelle
  • Inserire, aggiornare ed eliminare i dati
  • Eseguire query sui dati

Passare all'esercitazione successiva per ottenere informazioni sulla migrazione dei dati.