Implementación web de ASP.NET mediante Visual Studio: preparación de la implementación de bases de datos

Descarga del proyecto de inicio

En esta serie de tutoriales se muestra cómo implementar (publicar) una aplicación web de ASP.NET en Azure App Service Web Apps o en un proveedor de hospedaje de terceros, mediante Visual Studio 2012 o Visual Studio 2010. Para obtener información sobre la serie de tutoriales, vea el primer tutorial de la serie.

Información general

En este tutorial se muestra cómo preparar el proyecto para la implementación de la base de datos. La estructura de la base de datos y algunos (no todos) de los datos de las dos bases de datos de la aplicación deben implementarse en los entornos de pruebas, ensayo y producción.

Normalmente, a medida que desarrolla una aplicación, se introducen datos de prueba en una base de datos que no desea implementar en un sitio activo. Sin embargo, es posible que también tenga algunos datos de producción que quiera implementar. En este tutorial configurará el proyecto Contoso University y preparará scripts SQL para que se incluyan los datos correctos al implementar.

Aviso: Si recibe un mensaje de error o algo no funciona mientras recorre el tutorial, asegúrese de comprobar la página de solución de problemas.

SQL Server Express LocalDB

La aplicación de ejemplo usa LocalDB de SQL Server Express. SQL Server Express es la edición gratuita de SQL Server. Normalmente se usa durante el desarrollo porque se basa en el mismo motor de base de datos que las versiones completas de SQL Server. Puede probar con SQL Server Express y asegurarse de que la aplicación se comportará igual en producción, con algunas excepciones para las características que varían entre ediciones de SQL Server.

LocalDB es un modo de ejecución especial de SQL Server Express que permite trabajar con bases de datos como archivos .mdf. Normalmente, los archivos de base de datos LocalDB se conservan en la carpeta App_Data de un proyecto web. La característica de instancia de usuario de SQL Server Express también le permite trabajar con archivos .mdf, pero la característica de instancia de usuario está en desuso; por lo tanto, se recomienda LocalDB para trabajar con archivos .mdf.

Normalmente, SQL Server Express no se usa para aplicaciones web en producción. LocalDB en particular no se recomienda para su uso en producción con una aplicación web porque no está diseñado para trabajar con IIS.

En Visual Studio 2012, LocalDB se instala de forma predeterminada con Visual Studio. En Visual Studio 2010 y versiones anteriores, SQL Server Express (sin LocalDB) se instala de forma predeterminada con Visual Studio; es por eso que lo instaló como uno de los requisitos previos del primer tutorial de esta serie.

Para obtener más información sobre las ediciones de SQL Server, incluida LocalDB, consulte los siguientes recursos Trabajando con bases de datos de SQL Server.

Entity Framework y Proveedores universales

Para el acceso a la base de datos, la aplicación Contoso University requiere el siguiente software que se debe implementar con la aplicación porque no se incluye en .NET Framework:

Dado que este software se incluye en paquetes NuGet, el proyecto ya está configurado para que los ensamblados necesarios se implementen con el proyecto. (Los vínculos apuntan a las versiones actuales de estos paquetes, que podrían ser más recientes que lo que está instalado en el proyecto de inicio que descargó para este tutorial).

Si va a implementar en un proveedor de hospedaje de terceros en lugar de Azure, asegúrese de usar Entity Framework 5.0 o posterior. Las versiones anteriores de migraciones de Code First requieren plena confianza y la mayoría de los proveedores de hospedaje ejecutarán la aplicación en confianza media. Para obtener más información sobre la confianza media, consulte el tutorial Implementación en IIS como entorno de prueba.

Configuración de migraciones de Code First para la implementación de bases de datos de aplicaciones

Code First administra la base de datos de aplicaciones de Contoso University y la implementará mediante migraciones de Code First. Para obtener información general sobre la implementación de bases de datos mediante migraciones de Code First, consulte el primer tutorial de esta serie.

Al implementar una base de datos de aplicación, normalmente no solo se implementa la base de datos de desarrollo con todos los datos de ella en producción, ya que gran parte de los datos de ella probablemente solo están allí con fines de prueba. Por ejemplo, los nombres de los alumnos de una base de datos de prueba son ficticios. Por otro lado, a menudo no se puede implementar solo la estructura de la base de datos sin datos en ella. Algunos de los datos de la base de datos de prueba pueden ser datos reales y deben estar allí cuando los usuarios empiecen a usar la aplicación. Por ejemplo, la base de datos puede tener una tabla que contenga valores de notas válidos o nombres de departamento reales.

Para simular este escenario común, configurará un método de migraciones Seed de Code First que inserta en la base de datos solo los datos que desea que estén en producción. Este método Seed no debe insertar datos de prueba porque se ejecutará en producción después de que Code First cree la base de datos en producción.

En versiones anteriores de Code First antes de que se publicara Migraciones, era habitual que los métodos Seed insertaran también datos de prueba, ya que, con cada cambio de modelo durante el desarrollo, la base de datos tenía que eliminarse y volver a crearse desde cero. Con Migraciones de Code First, los datos de prueba se conservan tras los cambios en la base de datos, por lo que incluir datos de prueba en el método Seed no suele ser necesario. El proyecto que descargó usa el método de incluir todos los datos en el método Seed de una clase de inicializador. En este tutorial, deshabilitará esa clase de inicializador y habilitará Migraciones. A continuación, actualizará el método Seed en la clase de configuración de Migraciones para que inserte solo los datos que desea insertar en producción.

En el diagrama siguiente se muestra el esquema de la base de datos de aplicación:

School_database_diagram

En estos tutoriales, se supone que las tablas Student y Enrollment deben estar vacías cuando el sitio se implemente por primera vez. Las demás tablas contienen datos que tienen que cargarse previamente cuando la aplicación pasa a estar activa.

Deshabilitar el inicializador

Dado que va a usar migraciones de Code First, no tiene que usar el inicializador DropCreateDatabaseIfModelChanges de Code First. El código de este inicializador se encuentra en el archivo SchoolInitializer.cs del proyecto ContosoUniversity.DAL. Un valor en el elemento appSettings del archivo Web.config hace que este inicializador se ejecute siempre que la aplicación intente acceder a la base de datos por primera vez:

<appSettings>
  <add key="Environment" value="Dev" />
  <add key="DatabaseInitializerForType ContosoUniversity.DAL.SchoolContext, ContosoUniversity.DAL" value="ContosoUniversity.DAL.SchoolInitializer, ContosoUniversity.DAL" />
</appSettings>

Abra el archivo Web.config de la aplicación y quite o marque como comentario el elemento add que especifica la clase de inicializador Code First. El elemento appSettings ahora tiene el siguiente aspecto:

<appSettings>
  <add key="Environment" value="Dev" />
</appSettings>

Nota:

Otra manera de especificar una clase de inicializador es llamar a Database.SetInitializer en el método Application_Start del archivo Global.asax. Si va a habilitar Migraciones en un proyecto que usa ese método para especificar el inicializador, quite esa línea de código.

Nota:

Si usa Visual Studio 2013, agregue los pasos siguientes entre los pasos 2 y 3: (a) En PMC, escriba "update-package entityframework -version 6.1.1" para obtener la versión actual de EF. A continuación, (b) compile el proyecto para obtener una lista de errores de compilación y corregirlos. Elimine las instrucciones using para los espacios de nombres que ya no existen, haga clic con el botón derecho y haga clic en Resolver para agregar instrucciones using donde se necesiten y cambie las apariciones de System.Data.EntityState a System.Data.Entity.EntityState.

Habilitación de migraciones de Code First

  1. Asegúrese de que el proyecto ContosoUniversity (no ContosoUniversity.DAL) esté establecido como proyecto de inicio. En Explorador de soluciones, haga clic con el botón derecho en el proyecto ContosoUniversity y seleccione Establecer como proyecto de inicio. Las migraciones de Code First buscarán en el proyecto de inicio para buscar la cadena de conexión de la base de datos.

  2. En el menú Herramientas, elija Administrador de paquetes NuGet>Consola del Administrador de paquetes.

    Selecting_Package_Manager_Console

  3. En la parte superior de la ventana Consola del administrador de paquetes, seleccione ContosoUniversity.DAL como proyecto predeterminado y, a continuación, en la confirmación PM>, escriba "enable-migrations".

    enable-migrations command

    (Si recibe un error que indica que no se reconoce el comando enable-migrations, escriba el comando update-package EntityFramework -Reinstall e inténtelo de nuevo).

    Este comando crea una carpeta Migrations en el proyecto ContosoUniversity.DAL y coloca en esa carpeta dos archivos: un archivo Configuration.cs que puede usar para configurar migraciones y un archivo InitialCreate.cs para la primera migración que crea la base de datos.

    Migrations folder

    Ha seleccionado el proyecto DAL en la lista desplegable Proyecto predeterminado de la Consola del administrador de paquetes porque el comando enable-migrations debe ejecutarse en el proyecto que contiene la clase de contexto Code First. Cuando esa clase se encuentra en un proyecto de biblioteca de clases, Migraciones de Code First busca la cadena de conexión de base de datos en el proyecto de inicio de la solución. En la solución ContosoUniversity, el proyecto web se ha establecido como proyecto de inicio. Si no desea designar el proyecto que tiene la cadena de conexión como proyecto de inicio en Visual Studio, puede especificar el proyecto de inicio en el comando de PowerShell. Para ver la sintaxis del comando, escriba el comando get-help enable-migrations.

    El comando enable-migrations creó automáticamente la primera migración porque la base de datos ya existe. Una alternativa es hacer que migraciones creen la base de datos. Para ello, use el Explorador de servidores el Explorador de objetos de SQL Server para eliminar la base de datos ContosoUniversity antes de habilitar migraciones. Después de habilitar las migraciones, cree la primera migración manualmente escribiendo el comando "add-migration InitialCreate". Después, puede crear la base de datos escribiendo el comando "update-database".

Configuración del método Seed

Para este tutorial, agregará datos fijos agregando código al método Seed de la clase Configuration de Migraciones de Code First. Migraciones de Code First llama al método Seed después de cada migración.

Dado que el método Seed se ejecuta después de cada migración, ya hay datos en las tablas después de la primera migración. Para controlar esta situación, usará el método AddOrUpdate para actualizar las filas que ya se han insertado o insertarlas si aún no existen. Es posible que el método AddOrUpdate no sea la mejor opción para su escenario. Para más información, consulte Cuidado con el método AddOrUpdate de EF 4.3 en el blog de Julie Lerman.

  1. Abra el archivo Configuration.cs y reemplace los comentarios del método Seed por el código siguiente:

    var instructors = new List<Instructor>
    {   
        new Instructor { FirstMidName = "Kim",     LastName = "Abercrombie", HireDate = DateTime.Parse("1995-03-11"), OfficeAssignment = new OfficeAssignment { Location = "Smith 17" } },
        new Instructor { FirstMidName = "Fadi",    LastName = "Fakhouri",    HireDate = DateTime.Parse("2002-07-06"), OfficeAssignment = new OfficeAssignment { Location = "Gowan 27" } },
        new Instructor { FirstMidName = "Roger",   LastName = "Harui",       HireDate = DateTime.Parse("1998-07-01"), OfficeAssignment = new OfficeAssignment { Location = "Thompson 304" } },
        new Instructor { FirstMidName = "Candace", LastName = "Kapoor",      HireDate = DateTime.Parse("2001-01-15") },
        new Instructor { FirstMidName = "Roger",   LastName = "Zheng",       HireDate = DateTime.Parse("2004-02-12") }
    };
    instructors.ForEach(s => context.Instructors.AddOrUpdate(i => i.LastName, s));
    context.SaveChanges();
    
    var departments = new List<Department>
    {
        new Department { Name = "English",     Budget = 350000, StartDate = DateTime.Parse("2007-09-01"), PersonID = 1 },
        new Department { Name = "Mathematics", Budget = 100000, StartDate = DateTime.Parse("2007-09-01"), PersonID = 2 },
        new Department { Name = "Engineering", Budget = 350000, StartDate = DateTime.Parse("2007-09-01"), PersonID = 3 },
        new Department { Name = "Economics",   Budget = 100000, StartDate = DateTime.Parse("2007-09-01"), PersonID = 4 }
    };
    departments.ForEach(s => context.Departments.AddOrUpdate(d => d.Name, s));
    context.SaveChanges();
    
    var courses = new List<Course>
    {
        new Course { CourseID = 1050, Title = "Chemistry",      Credits = 3, DepartmentID = 3 },
        new Course { CourseID = 4022, Title = "Microeconomics", Credits = 3, DepartmentID = 4 },
        new Course { CourseID = 4041, Title = "Macroeconomics", Credits = 3, DepartmentID = 4 },
        new Course { CourseID = 1045, Title = "Calculus",       Credits = 4, DepartmentID = 2 },
        new Course { CourseID = 3141, Title = "Trigonometry",   Credits = 4, DepartmentID = 2 },
        new Course { CourseID = 2021, Title = "Composition",    Credits = 3, DepartmentID = 1 },
        new Course { CourseID = 2042, Title = "Literature",     Credits = 4, DepartmentID = 1 }
    };
    courses.ForEach(s => context.Courses.AddOrUpdate(s));
    context.SaveChanges();
    
    courses[0].Instructors.Add(instructors[0]);
    courses[0].Instructors.Add(instructors[1]);
    courses[1].Instructors.Add(instructors[2]);
    courses[2].Instructors.Add(instructors[2]);
    courses[3].Instructors.Add(instructors[3]);
    courses[4].Instructors.Add(instructors[3]);
    courses[5].Instructors.Add(instructors[3]);
    courses[6].Instructors.Add(instructors[3]);
    context.SaveChanges();
    
  2. Las referencias a List tienen líneas onduladas rojas bajo ellas porque aún no tiene una instrucción using para su espacio de nombres. Haga clic con el botón derecho en una de las instancias de List y haga clic en Resolver y, a continuación, haga clic en Usar System.Collections.Generic.

    Resolve with using statement

    Esta selección de menú agrega el código siguiente a las instrucciones using cerca de la parte superior del archivo.

    using System.Collections.Generic;
    
  3. Presione Ctrl+Mayús+B para compilar el proyecto.

El proyecto ya está listo para implementar la base de datos ContosoUniversity. Después de implementar la aplicación, la primera vez que la ejecute y vaya a una página que acceda a la base de datos, Code First creará la base de datos y ejecutará este método Seed.

Nota:

Agregar código al método Seed es una de muchas maneras de insertar datos fijos en la base de datos. Una alternativa es agregar código a los métodos Up y Down de cada clase de migración. Los métodos Up y Down contienen código que implementa los cambios de la base de datos. Verá ejemplos de ellos en el tutorial Implementación de una actualización de base de datos.

También puede escribir código que ejecute instrucciones SQL mediante el método Sql. Por ejemplo, si agregaba una columna Budget a la tabla Department y quería inicializar todos los presupuestos del departamento a 1000,00 USD como parte de una migración, podría agregar la siguiente línea de código al método Up para esa migración:

Sql("UPDATE Department SET Budget = 1000");

Creación de scripts para la implementación de bases de datos de pertenencia

La aplicación Contoso University usa el sistema de pertenencia ASP.NET y la autenticación de formularios para autenticar y autorizar a los usuarios. La página Actualizar créditos solo es accesible para los usuarios que están en el rol Administrador.

Ejecute la aplicación y haga clic en Cursos y, a continuación, haga clic en Actualizar créditos.

Click Update Credits

Aparece la página Iniciar sesión porque la página de Actualizar créditos requiere privilegios administrativos.

Escriba admin como nombre de usuario y devpwd como contraseña y haga clic en Iniciar sesión.

Log in page

Aparece la página Actualizar créditos.

Update Credits page

La información de usuario y rol se encuentra en la base de datos aspnet-ContosoUniversity especificada por la cadena de conexión DefaultConnection en el archivo Web.config.

Entity Framework Code First no administra esta base de datos, por lo que no se pueden usar migraciones para implementarla. Usará el proveedor dbDacFx para implementar el esquema de base de datos y configurará el perfil de publicación para ejecutar un script que insertará datos iniciales en tablas de base de datos.

Nota:

Se introdujo un nuevo sistema de pertenencia ASP.NET (ahora denominado ASP.NET Identity) con Visual Studio 2013. El nuevo sistema le permite mantener las tablas de aplicación y pertenencia en la misma base de datos y puede usar migraciones de Code First para implementar ambas. La aplicación de ejemplo usa el sistema de pertenencia de ASP.NET anterior, que no se puede implementar mediante migraciones de Code First. Los procedimientos para implementar esta base de datos de pertenencia también se aplican a cualquier otro escenario en el que la aplicación necesite implementar una base de datos de SQL Server que no sea creada por Entity Framework Code First.

Aquí también, normalmente no quiere los mismos datos en producción que tiene en desarrollo. Al implementar un sitio por primera vez, es habitual excluir la mayoría o todas las cuentas de usuario que cree para las pruebas. Por lo tanto, el proyecto descargado tiene dos bases de datos de pertenencia: aspnet-ContosoUniversity.mdf con usuarios de desarrollo y aspnet-ContosoUniversity-Prod.mdf con usuarios de producción. En este tutorial, los nombres de usuario son los mismos en ambas bases de datos: admin y nonadmin. Ambos usuarios tienen la contraseña devpwd en la base de datos de desarrollo y prodpwd en la base de datos de producción.

Implementará los usuarios de desarrollo en el entorno de prueba y los usuarios de producción en ensayo y producción. Para ello, creará dos scripts SQL en este tutorial, uno para desarrollo y otro para producción y, en tutoriales posteriores, configurará el proceso de publicación para ejecutarlos.

Nota:

La base de datos de pertenencia almacena un hash de contraseñas de cuenta. Para implementar cuentas de una máquina a otra, debe asegurarse de que las rutinas de hash no generan hash diferentes en el servidor de destino que en el equipo de origen. Generarán los mismos hash al usar Proveedores universales de ASP.NET, siempre y cuando no cambie el algoritmo predeterminado. El algoritmo predeterminado es HMACSHA256 y se especifica en el atributo de validación del elemento machineKey en el archivo Web.config.

Puede crear scripts de implementación de datos manualmente, mediante SQL Server Management Studio (SSMS) o mediante una herramienta de terceros. El resto de este tutorial le mostrará cómo hacerlo en SSMS, pero si no desea instalar y usar SSMS, puede obtener los scripts de la versión completa del proyecto y pasar a la sección donde los almacena en la carpeta de la solución.

Para instalar SSMS, instálelo desde el Centro de descarga: Microsoft SQL Server 2012 Express haciendo clic en ENU\x64\SQLManagementStudio_x64_ENU.exe o ENU\x86\SQLManagementStudio_x86_ENU.exe. Si elige el incorrecto para el sistema, no podrá instalarlo y puede probar el otro.

(Tenga en cuenta que se trata de una descarga de 600 megabytes. Puede tardar mucho tiempo en instalarse y requerirá un reinicio del equipo).

En la primera página del Centro de instalación de SQL Server, haga clic en Nueva instalación independiente de SQL Server o agregar características a una instalación existente y siga las instrucciones para aceptar las opciones predeterminadas.

Creación del script de base de datos de desarrollo

  1. Ejecute SSMS.

  2. En el cuadro de diálogo Conectar al servidor , escriba (localdb)\v11.0 como Nombre del servidor, deje Autenticación establecido en Autenticación de Windowsy, a continuación, haga clic en Conectar.

    SSMS Connect to Server

  3. En la ventana Explorador de objetos, expanda Bases de datos, haga clic con el botón derecho en aspnet-ContosoUniversity, haga clic en Tareas, a continuación, haga clic en Generar scripts.

    SSMS Generate Scripts

  4. En el cuadro de diálogo Generar y publicar scripts, haga clic en Establecer opciones de scripting.

    Puede omitir el paso Elegir objetos porque el valor predeterminado es Incluir en el script toda la base de datos y todos los objetos de base de datos y eso es lo que desea.

  5. Haga clic en Avanzado.

    SSMS Scripting Options

  6. En el cuadro de diálogo Opciones avanzadas de scripting, desplácese hacia abajo hasta Tipos de datos para incluir en el script y haga clic en la opción Solo datos de la lista desplegable.

  7. Cambie Incluir USE DATABASE en el script a Falso. Las instrucciones USE no son válidas para Azure SQL Database y no son necesarias para la implementación en SQL Server Express en el entorno de prueba.

    SSMS Script Data Only, no USE statement

  8. Haga clic en OK.

  9. En el cuadro de diálogo Generar y publicar scripts, el cuadro Nombre de archivo especifica dónde se creará el script. Cambie la ruta de acceso a la carpeta de la solución (la carpeta que tiene el archivo ContosoUniversity.sln) y el nombre de archivo a aspnet-data-dev.sql.

  10. Haga clic en Siguiente para ir a la pestaña Resumen y, a continuación, haga clic en Siguiente de nuevo para crear el script.

    SSMS Script Created

  11. Haga clic en Finalizar

Creación del script de base de datos de producción

Puesto que no ha ejecutado el proyecto con la base de datos de producción, aún no está asociado a la instancia de LocalDB. Por lo tanto, primero debe adjuntar la base de datos.

  1. En el Explorador de objetos de SSMS, haga clic con el botón derecho en Bases de datos y haga clic en Adjuntar.

    SSMS Attach

  2. En el cuadro de diálogo Adjuntar bases de datos, haga clic en Agregar y, a continuación, vaya al archivo aspnet-ContosoUniversity-Prod.mdf en la carpeta App_Data.

    SSMS Add .mdf file to attach

  3. Haga clic en OK.

  4. Siga el mismo procedimiento que usó anteriormente para crear un script para el archivo de producción. Asigne al archivo de script el nombre aspnet-data-prod.sql.

Resumen

Ambas bases de datos ya están listas para implementarse y tiene dos scripts de implementación de datos en la carpeta de la solución.

Data deployment scripts

En el siguiente tutorial se configuran las opciones de proyecto que afectan a la implementación y se configuran las transformaciones automáticas de archivos Web.config para las opciones que deben ser diferentes en la aplicación implementada.

Más información

Para obtener más información sobre NuGet, consulte Administración de bibliotecas de proyectos con NuGet y Documentación de NuGet. Si no desea usar NuGet, deberá aprender a analizar un paquete NuGet para determinar qué hace cuando se instala. (Por ejemplo, podría configurar transformaciones Web.config, configurar scripts de PowerShell para que se ejecuten en tiempo de compilación, etc.) Para obtener más información sobre cómo funciona NuGet, consulte Creación y publicación de un paquete y Transformaciones de código fuente y archivos de configuración.