Conexión de una aplicación ASP.NET con Azure SQL Database

Completado

Existen varias formas de conectarse a bases de datos del servicio Azure SQL Database desde una aplicación. Para aplicaciones .NET, puede usar la biblioteca System.Data.SqlClient.

La aplicación web de la universidad debe capturar y mostrar los datos que usted ha cargado en la base de datos SQL. En esta unidad aprenderá a conectarse a una base de datos desde una aplicación web y a usar la biblioteca System.Data.SqlClient para procesar los datos.

Introducción a la biblioteca System.Data.SqlClient

La biblioteca System.Data.SqlClient es una colección de tipos y métodos que puede usar para conectarse a una base de datos de SQL Server que se esté ejecutando localmente o en la nube en SQL Database. La biblioteca proporciona una interfaz generalizada para recuperar y mantener los datos. Puede usar la biblioteca System.Data.SqlClient para ejecutar comandos de Transact-SQL (T-SQL) y operaciones transaccionales, y para recuperar datos. Puede parametrizar estas operaciones para evitar problemas relacionados con los ataques por inyección de código SQL. Si se produce un error en una operación, la biblioteca System.Data.SqlClient proporciona información sobre el error a través de clases de excepciones y errores especializadas. Controle estas excepciones del mismo modo que cualquier otro tipo de excepción de una aplicación. NET.

La biblioteca System.Data.SqlClient está disponible en el paquete System.Data.SqlClient de NuGet.

Conexión a una base de datos única

Cree una conexión de base de datos mediante un objeto SqlConnection. Proporcione una cadena de conexión que especifique el nombre y la ubicación de la base de datos, las credenciales que deben usarse y otros parámetros relacionados con la conexión. Una cadena de conexión habitual a una base de datos única tiene este aspecto:

Server=tcp:<server-name>.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;

Puede encontrar la cadena de conexión de la base de datos única en la página Cadenas de conexión de la base de datos en Azure Portal.

En el ejemplo de código siguiente se muestra cómo crear un objeto SqlConnection:

using System.Data.SqlClient;

...

string connectionString = "Server=tcp:<server-name>.database.windows.net,...";
SqlConnection con = new SqlConnection(connectionString);

La conexión de base de datos no se establece hasta que abre la conexión. Normalmente, abrirá la conexión de manera inmediata antes de ejecutar una consulta o un comando de T-SQL.

con.Open();

Algunas bases de datos solo admiten un número finito de conexiones simultáneas. Por lo tanto, después de terminar de ejecutar un comando y recuperar los resultados, se recomienda cerrar la conexión y liberar los recursos que se hayan mantenido.

con.Close();

Otro enfoque común consiste en crear la conexión en una instrucción using. Esta estrategia cierra automáticamente la conexión cuando se completa la instrucción using. Pero también puede llamar explícitamente al método Close.

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

Definición de una consulta o un comando de T-SQL

Cree un objeto SqlCommand para especificar una consulta o un comando de T-SQL para ejecutar. En el ejemplo siguiente se muestra una instrucción DELETE de T-SQL que quita filas de un cliente determinado de la tabla dbo.Orders. Puede parametrizar los comandos. Este ejemplo utiliza un parámetro denominado CustID para el valor CustomerID. La línea que establece la propiedad CommandType del objeto SqlCommand en Text indica que el comando es una instrucción de T-SQL. También puede ejecutar un procedimiento almacenado en lugar de una instrucción de T-SQL. En ese caso, establezca CommandType en 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));

El parámetro final para el constructor SqlCommand de este ejemplo es la conexión que se usará para ejecutar el comando.

En el ejemplo siguiente se muestra una consulta que combina las tablas dbo.Customers y dbo.Orders para generar una lista con los nombres de los clientes y sus pedidos.

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;

Ejecución de un comando

Si el objeto SqlCommand hace referencia a una instrucción de T-SQL que no devuelve un conjunto de resultados, ejecute el comando con el método ExecuteNonQuery. Si el comando se ejecuta correctamente, devuelve el número de filas afectadas por la operación. En el ejemplo siguiente se muestra cómo ejecutar el comando deleteOrdersForCustomer mostrado anteriormente.

int numDeleted = deleteOrdersForCustomer.ExecuteNonQuery();

Si espera que el comando tarde un tiempo en ejecutarse, puede usar el método ExecuteNonQueryAsync para realizar la operación de forma asincrónica.

Ejecución de una consulta y captura de los datos

Si SqlCommand contiene una instrucción SELECT de T-SQL, ejecútela con el método ExecuteReader. Este método devuelve un objeto SqlDataReader que puede usar para iterar los resultados y procesar las filas de una en una. Los datos de un objeto SqlReader deben recuperarse con el método Read. Este método devuelve true si se encuentra una fila y false si no hay más filas por leer. Una vez que se ha leído una fila, los datos de esa fila están disponibles en los campos del objeto SqlReader. Cada campo tiene el mismo nombre que su columna correspondiente de la instrucción SELECT original. Sin embargo, los datos de cada campo se recuperan como un elemento object sin tipo, por lo que debe convertirlos al tipo adecuado para poder usarlos. El código siguiente muestra cómo ejecutar el comando queryCmd mostrado anteriormente para capturar los datos por filas, de una en una.

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

Control de excepciones y errores

Se pueden producir excepciones y errores por varias razones cuando se utiliza una base de datos. Por ejemplo, puede que esté intentando acceder a una tabla que ya no existe. Puede detectar errores de T-SQL con el tipo SqlException.

Varios eventos o problemas en la base de datos pueden desencadenar una excepción. Un objeto SqlException tiene una propiedad denominada Errors que contiene una colección de objetos SqlError. Estos objetos proporcionan los detalles de cada error. El ejemplo siguiente muestra cómo detectar un elemento SqlException y procesar los errores que contiene.

...
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()}");
        }
    }
}