Verbinding maken tussen een ASP.NET-toepassing en Azure SQL Database

Voltooid

U kunt op verschillende manieren vanuit een toepassing verbinding maken met databases in de Azure SQL Database-service. Voor .NET-apps kunt u de System.Data.SqlClient-bibliotheek gebruiken.

De web-app voor de universiteit moet de gegevens die u hebt geüpload naar de SQL-database ophalen en weergeven. In deze les leert u hoe u vanuit een web-app verbinding maakt met een database en hoe u de System.Data.SqlClient bibliotheek gebruikt om gegevens te verwerken.

Overzicht van de System.Data.SqlClient-bibliotheek

De System.Data.SqlClient-bibliotheek bestaat uit een verzameling typen en methoden die u kunt gebruiken om verbinding te maken met een SQL Server-database die zich on-premises of in de cloud in SQL Database wordt uitgevoerd. De bibliotheek biedt een algemene interface voor het ophalen en beheren van gegevens. U kunt de System.Data.SqlClient bibliotheek gebruiken om Transact-SQL-opdrachten (T-SQL) en transactionele bewerkingen uit te voeren en om gegevens op te halen. U kunt parameters aan deze bewerkingen toevoegen om problemen te voorkomen die verband houden met SQL-injectieaanvallen. Als een bewerking mislukt, worden de foutgegevens van de System.Data.SqlClient-bibliotheek beschikbaar gemaakt via gespecialiseerde uitzonderings- en foutklassen. U handelt deze uitzonderingen op dezelfde manier af als elk ander type uitzondering in een .NET-toepassing.

De System.Data.SqlClient-bibliotheek is beschikbaar in het NuGet-pakket System.Data.SqlClient.

Verbinding maken met een individuele database

U gebruikt een SqlConnection-object om een databaseverbinding te maken. U geeft een verbindingsreeks op met de naam en locatie van de database, de te gebruiken referenties en andere parameters met betrekking tot de verbinding. Een gebruikelijke verbindingsreeks voor een individuele database ziet er zo uit:

Server=tcp:myserver.database.windows.net,1433;Initial Catalog=mydatabase;Persist Security Info=False;User ID=myusername;Password=mypassword;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;

U vindt de verbindingsreeks voor uw individuele database op de pagina Verbindingsreeksen voor uw database in de Azure-portal.

In het volgende codevoorbeeld ziet u hoe u een SqlConnection-object maakt:

using System.Data.SqlClient;

...

string connectionString = "Server=tcp:myserver.database.windows.net,...";
SqlConnection con = new SqlConnection(connectionString);

De verbinding met de database wordt pas tot stand gebracht als u de verbinding opent. Normaal gesproken opent u de verbinding direct voordat u een T-SQL-opdracht of -query uitvoert.

con.Open();

Sommige databases ondersteunen slechts een beperkt aantal gelijktijdige verbindingen. Dus nadat u een opdracht hebt uitgevoerd en de resultaten hebt opgehaald, is het raadzaam om de verbinding te sluiten en eventuele resources vrij te geven.

con.Close();

Een andere algemene aanpak bestaat uit het maken van de verbinding in een using-instructie. In deze strategie wordt de verbinding automatisch gesloten als de using-instructie is voltooid. U kunt de Close-methode echter ook expliciet aanroepen.

using (SqlConnection con = new SqlConnection(connectionString))
{
    // Open and Use the connection here
    con.Open();
    ...
}
// Connection is now closed

Een T-SQL-opdracht of -query definiëren

Maak een SqlCommand object om een T-SQL-opdracht of -query op te geven die moet worden uitgevoerd. In het volgende voorbeeld ziet u een T-SQL-instructie DELETE waarmee rijen voor een bepaalde klant uit de dbo.Orders tabel worden verwijderd. U kunt parameters aan de opdrachten toevoegen. In dit voorbeeld wordt een parameter met de naam CustID gebruikt voor de CustomerID waarde. De regel waarmee de CommandType eigenschap van het SqlCommand object wordt ingesteld, Text geeft aan dat de opdracht een T-SQL-instructie is. U kunt ook een opgeslagen procedure uitvoeren in plaats van een T-SQL-instructie. Stel in dat geval CommandType in op StoredProcedure.

SqlCommand deleteOrdersForCustomer = new SqlCommand("DELETE FROM Orders WHERE CustomerID = @custID", con);
deleteOrdersForCustomer.CommandType = CommandType.Text;
string customerID = <prompt the user for a customer to delete>;
deleteOrdersForCustomer.Parameters.Add(new SqlParameter("custID", customerID));

De laatste parameter voor de SqlCommand-constructor in dit voorbeeld, is de verbinding die wordt gebruikt om de opdracht uit te voeren.

In het volgende voorbeeld ziet u een query waarmee de dbo.Customers en dbo.Orders tabellen worden samengevoegd om een lijst met klantnamen en hun orders te maken.

SqlCommand queryCmd = new SqlCommand(
                    @"SELECT c.FirstName, c.LastName, o.OrderID
                      FROM Customers c JOIN Orders o
                      ON c.CustomerID = o.CustomerID", con);
queryCmd.CommandType = CommandType.Text;

Een opdracht uitvoeren

Als uw SqlCommand object verwijst naar een T-SQL-instructie die geen resultatenset retourneert, voert u de opdracht uit met behulp van de ExecuteNonQuery methode. Als de opdracht slaagt, wordt het aantal rijen geretourneerd dat wordt beïnvloed door de bewerking. In het volgende voorbeeld ziet u hoe u de deleteOrdersForCustomer eerder weergegeven opdracht uitvoert.

int numDeleted = deleteOrdersForCustomer.ExecuteNonQuery();

Als u vermoed dat het uitvoeren van de opdracht enige tijd in beslag neemt, kunt u de ExecuteNonQueryAsync-methode gebruiken om de bewerking asynchroon uit te voeren.

Een query uitvoeren en gegevens ophalen

Als uw SqlCommand T-SQL SELECT-instructie bevat, voert u deze uit met behulp van de ExecuteReader methode. Met deze methode wordt een SqlDataReader-object geretourneerd dat u kunt gebruiken om de resultaten te doorlopen en elke rij afzonderlijk te verwerken. U haalt de gegevens uit een SqlReader-object op met de Read-methode. Met deze methode wordt waar geretourneerd als een rij wordt gevonden. Er wordt onwaar geretourneerd als er geen rijen meer zijn om te lezen. Als een rij is gelezen, zijn de gegevens van die rij beschikbaar in de velden in het SqlReader-object. Elk veld heeft dezelfde naam als de overeenkomende kolom in de oorspronkelijke SELECT-instructie. De gegevens in elk veld worden echter opgehaald als een niet-getypeerd object. U moet deze dus converteren naar het juiste type voordat u ze kunt gebruiken. De volgende code laat zien hoe u de queryCmd eerder geïllustreerde opdracht uitvoert om de gegevens één rij tegelijk op te halen.

SqlDataReader rdr = queryCmd.ExecuteReader();

// Read the data a row at a time
while (rdr.Read())
{
    string firstName = rdr["FirstName"].ToString();
    string lastName = rdr["LastName"].ToString();
    int orderID = Convert.ToInt32(rdr["OrderID"]);

    // Process the data
    ...
}

Omgaan met uitzonderingen en fouten

Als u een database gebruikt, kunnen er om verschillende redenen uitzonderingen en fouten optreden. U wilt bijvoorbeeld een tabel openen die niet meer bestaat. U kunt T-SQL-fouten ondervangen met behulp van het SqlException type.

Verschillende gebeurtenissen of problemen in de database kunnen een uitzondering activeren. Een SqlException-object bezit de eigenschap Errors die een verzameling SqlError-objecten bevat. Deze objecten laten de details van elke fout zien. In het volgende voorbeeld ziet u hoe een SqlException afvangt en de fouten verwerkt die deze bevat.

...
using (SqlConnection con = new SqlConnection(connectionString))
{
    SqlCommand command = new SqlCommand("DELETE FROM ...", con);
    try
    {
        con.Open();
        command.ExecuteNonQuery();
    }
    catch (SqlException ex)
    {
        for (int i = 0; i < ex.Errors.Count; i++)
        {
            Console.WriteLine($"Index # {i} Error: {ex.Errors[i].ToString()}");
        }
    }
}