Tutorial: Diseño de una base de datos relacional en Azure SQL Database con C# y ADO.NET

Se aplica a:Azure SQL Database

Azure SQL Database es una base de datos como servicio (DBaaS) relacional en Microsoft Cloud (Azure). En este tutorial se aprenderá a usar Azure Portal y ADO.NET con Visual Studio para:

  • Crear una base de datos mediante Azure Portal
  • Configurar una regla de firewall por IP de nivel de servidor mediante Azure Portal
  • Conectarse a la base de datos con ADO.NET y Visual Studio
  • Crear tablas con ADO.NET
  • Insertar, actualizar y eliminar datos con ADO.NET
  • Consultar datos con ADO.NET

Sugerencia

El siguiente módulo gratuito de Microsoft Learn le enseña cómo Desarrollar y configurar una aplicación de ASP.NET que consulta una instancia de Azure SQL Database, incluida la creación de una base de datos simple.

Requisitos previos

Inicio de sesión en Azure Portal

Inicie sesión en Azure Portal.

Creación de una regla de firewall de IP de nivel de servidor

SQL Database crea un firewall de IP en el nivel de servidor. Este firewall evita que las herramientas y aplicaciones externas se conecten al servidor o a las bases de datos de este, a menos que una regla de firewall permita sus direcciones IP. Para habilitar la conectividad externa a la base de datos, primero debe agregar una regla de firewall para la dirección IP (o un intervalo de direcciones IP). Siga estos pasos para crear una regla de firewall de IP de nivel de servidor.

Importante

SQL Database se comunica a través del puerto 1433. Si intenta conectarse a este servicio desde dentro de una red corporativa, es posible que el firewall de la red no permita el tráfico de salida a través del puerto 1433. En ese caso, no puede conectarse a la base de datos, salvo que el administrador abra el puerto 1433.

  1. Cuando se haya finalizado la implementación, seleccione Bases de datos SQL en el menú de la izquierda y, después, elija yourDatabase en la página Bases de datos SQL. Se abre la página de información general de la base de datos, que muestra el nombre del servidor completo (por ejemplo, sample-svr.database.windows.net) y proporciona opciones para otras configuraciones.

  2. Copie el nombre completo del servidor para conectarse a su servidor y a sus bases de datos de SQL Server Management Studio.

    Screenshot of the Azure portal, database overview page, with the server name highlighted.

  3. Seleccione Redes en Configuración. Elija la pestaña Acceso público y, después, seleccione Redes seleccionadas en Public network access (Acceso a la red pública) para mostrar la sección Reglas de firewall.

    Screenshot of the Azure portal, networking page, showing where to set the server-level IP firewall rule.

  4. Seleccione Agregar IP de cliente en la barra de herramientas para agregar la dirección IP actual a la nueva regla de firewall por IP. La regla de firewall de IP puede abrir el puerto 1433 para una única dirección IP o un intervalo de direcciones IP.

  5. Seleccione Guardar. Se crea una regla de firewall de IP en el nivel de servidor para el puerto 1433 de la dirección IP actual en el servidor.

  6. Seleccione Aceptar y después cierre la página Configuración de firewall.

Ahora la dirección IP puede pasar a través del firewall de IP; además, puede conectarse a la base de datos mediante SQL Server Management Studio u otra herramienta que elija. Asegúrese de usar la cuenta de administración de servidor que creó anteriormente.

Importante

De forma predeterminada, el acceso a través del firewall por IP de SQL Database está habilitado para todos los servicios de Azure. Seleccione DESACTIVADO en esta página para deshabilitar todos los servicios de Azure.

Ejemplo de programa C#

En las secciones siguientes de este artículo se presenta un programa C# que usa ADO.NET para enviar instrucciones Transact-SQL (T-SQL) a SQL Database. El programa C# muestra las acciones siguientes:

Diagrama de relaciones de entidades (ERD)

Las instrucciones CREATE TABLE emplean la palabra clave REFERENCES para crear una relación de clave externa (FK) entre dos tablas. Si usa tempdb, convierta en comentario la palabra clave --REFERENCES con un par de guiones iniciales.

El ERD muestra la relación entre ambas tablas. Los valores de la columna child de tabEmployee.DepartmentCode están limitados a los valores de la columna parent de tabDepartment.DepartmentCode.

ERD showing foreign key

Nota:

Tiene la opción de editar el código T-SQL para agregar un carácter # inicial a los nombres de tabla, lo que los crea como tablas temporales en tempdb. Esto resulta útil como demostración, cuando no hay ninguna base de datos de prueba disponible. Las referencias a claves externas no se aplican durante su uso y las tablas temporales se eliminan automáticamente cuando se cierra la conexión después de que el programa termina la ejecución.

Para compilarlo y ejecutarlo

El programa en C# es lógicamente un archivo .cs y se divide físicamente en varios bloques de código, para que cada bloque resulte más fácil de comprender. Para compilar y ejecutar este programa, realice los pasos siguientes:

  1. Cree un proyecto C# en Visual Studio. El tipo de proyecto debe ser una Consola, que se encuentra en Plantillas>Visual C#>Escritorio de Windows>Aplicación de consola (.NET Framework) .

  2. En el archivo Program.cs, reemplace las líneas de código iniciales con los pasos siguientes:

    1. Copie y pegue los siguientes bloques de código, en la misma secuencia que se presentan. Consulte Conexión a la base de datos, Generación de T-SQL y Envío a la base de datos.

    2. Cambie los valores siguientes en el método Main:

      • cb.DataSource
      • cb.UserID
      • cb.Password
      • cb.InitialCatalog
  3. Compruebe que se haga referencia al ensamblado System.Data.dll. Para comprobarlo, expanda el nodo Referencias en el panel Explorador de soluciones.

  4. Para compilar y ejecutar el programa desde Visual Studio, seleccione el botón Iniciar. La salida del informe se muestra en una ventana de programa, aunque los valores de GUID variarán entre series de pruebas.

    =================================
    T-SQL to 2 - Create-Tables...
    -1 = rows affected.
    
    =================================
    T-SQL to 3 - Inserts...
    8 = rows affected.
    
    =================================
    T-SQL to 4 - Update-Join...
    2 = rows affected.
    
    =================================
    T-SQL to 5 - Delete-Join...
    2 = rows affected.
    
    =================================
    Now, SelectEmployees (6)...
    8ddeb8f5-9584-4afe-b7ef-d6bdca02bd35 , Alison , 20 , acct , Accounting
    9ce11981-e674-42f7-928b-6cc004079b03 , Barbara , 17 , hres , Human Resources
    315f5230-ec94-4edd-9b1c-dd45fbb61ee7 , Carol , 22 , acct , Accounting
    fcf4840a-8be3-43f7-a319-52304bf0f48d , Elle , 15 , NULL , NULL
    View the report output here, then press any key to end the program...
    

Conexión a SQL Database mediante 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();
        }

Métodos que devuelven instrucciones T-SQL

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

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

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;
    ";
}

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;
    ";
}

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;
    ";
}

Envío de T-SQL a la base de datos

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));
            }
        }
    }
}

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
}

Sugerencia

Para obtener más información sobre cómo escribir consultas SQL, visite Tutorial: Escritura de instrucciones Transact-SQL.

Paso siguiente

Prosiga con el tutorial siguiente para aprender sobre la migración de datos.