El proyecto del nivel de datos contiene una serie de componentes que traducen los objetos de clase en Entidades Blip en tablas de bases de datos relacionales y manejan operaciones de creación, recuperación, actualización y eliminación (CRUD) de esos datos:
- El contexto de los datos, ApplicationDbContext en nuestro ejemplo.
- Código de configuración de migración de datos de Entity Framework, incluido el método Seed que permite llenar la base de datos con datos de referencia cuando se crea la base de datos.
- Clases de repositorio que intercambian datos entre el contexto de los datos y la capa de lógica empresarial de la aplicación.
Necesitamos realizar una serie de acciones para crear la base de datos, sembrarla con datos y hacerla accesible a nuestro proyecto web.
Añadir una referencia al Proyecto de Entidades
Blip.Data se basa en las clases que definimos en Blip.Entities por lo que necesitamos añadir una referencia correspondiente.
Utilizando el mismo proceso que utilizamos para añadir referencias a Blip.Web , abra el Administrador de Referencias para Blip.Data , y añada una referencia a Blip.Data .
Especificación de la ubicación física de la base de datos
Podemos poner los archivos de la base de datos física en una carpeta App_Data bajo la carpeta del proyecto. Alternativamente, si no especificamos una ubicación específica para los archivos, Visual Studio pondrá las bases de datos creadas en el servidor de desarrollo local de SQL Server Express en el siguiente directorio:
Si utilizamos el directorio App_Data , tendremos que especificar la ruta en los archivos de configuración.
Por consiguiente, este es un paso opcional. No hacerlo no afectará al funcionamiento de la solución.
Creación de cadenas de conexión
Nuestra solución requiere una cadena de conexión para identificar el almacén de datos; en este caso, una base de datos de servidor SQL, asociada al contexto de datos ApplicationDbContext que será utilizada por Entity Framework y nuestros métodos de repositorio. Es posible que los proyectos tengan más de un contexto de datos y más de un tipo de almacén de datos. Cada uno requiere una cadena de conexión.
Las cadenas de conexión son la fuente de mucha angustia para los desarrolladores. Mientras que esta guía se esforzará por guiarlo en torno a un número de minas terrestres de cadena de conexión, su entorno de desarrollo, y por lo tanto los problemas que encuentre, pueden variar. La sección Otros Recursos de esta guía incluye algunos recursos valiosos dedicados a las turbias profundidades de las cadenas de conexión.
En nuestro proyecto de ejemplo Blip.Projects , necesitamos tener nuestra cadena de conexión en dos lugares y tiene que ser exactamente la misma en ambos lugares:
ProjectFileBlip.DataApp.configBlip.WebWeb.config
Estos son archivos en formato XML. En ambos proyectos los archivos .config se encuentran en la raíz del proyecto, debajo de las carpetas.
Nota importante: si su proyecto de nivel de datos ( Blip.Data en nuestro ejemplo) contiene un archivo Web.config en lugar de un archivo App.config , consulte la sección Edición del tipo de proyecto a continuación.
Para nuestro proyecto de ejemplo, la sección de la cadena de conexión es la siguiente:
123<connectionStrings;
;addname=»ApplicationDbContext «connectionString=»Data Source=(localdb)ProjectsV13;Initial Catalog=BlipData;Integrated Security=SSPI;AttachDBFilename=BlipData.mdf «providerName=»System.Data.SqlClient»/;/connectionStrings
xml
Tenga en cuenta los siguientes puntos importantes para identificar algunas de las formas en las que su cadena de conexión podría tener que diferir para funcionar:
- Si utiliza una versión diferente de Visual Studio o una base de datos distinta de la versión de desarrollo de SQL Server Express (localdb) como base de datos, la parte de DataSource de su cadena de conexión podría ser diferente.
- Si desea colocar los archivos físicos de la base de datos en un directorio distinto de la ubicación predeterminada, como el directorio App_Data, como se ha mencionado anteriormente, la parte de la cadena AttachDBFilename deberá incluir la ruta de acceso totalmente cualificada al directorio. Esta ruta debe existir antes de usar el comando Update-Database de Entity Framework.
La sección connectionStrings del archivo .config suele estar situada cerca de la parte superior del archivo, dentro del elemento (que define el archivo de configuración).
Creando el contexto de los datos
El contexto de datos para nuestra solución es simple y directo. Hay unos pocos requisitos de configuración y unas pocas porciones que deben ser mantenidas manualmente a medida que el desarrollo de la aplicación progresa.
Aquí está el código completo, seguido de notas sobre la configuración y el desarrollo:
Blip.DataContextoContexto.cs
1234567891011121314151617181920212223usando Entidad.de.Datos.del.Sistema;usando Entidad.de.Datos.del.Sistema.Convenciones.de.Configuración.Modelo;usando.Entidades.Blip.Cliente;usando.Entidades.Blip.Geografías;espacio.de.nombres.Blip. Datos{clase.públicaAplicaciónDbContexto:DbContexto{aplicación públicaDbContexto(): base("ApplicationDbContext"){}public DbSet<País;}; Países {get;set;}public DbSet<Cliente;} Clientes {get;set;}public DbSet<Región;} Regiones {get;set;}protectedoverridevoidOnModelCreating(DbModelBuilder modelBuilder){}}
csharp
Establecimiento del contexto de los datos
- Nuestra clase pública, ApplicationDbContext (que puede llamarse de todo), hereda la clase DbContext de System.Data.Entity, un espacio de nombres proporcionado por Entity Framework.
- Si añadimos declaraciones al método de creación de modelos, es probable que utilicemos miembros de las convenciones de configuración de modelos de entidades de datos del sistema. Como no estamos haciendo eso en Blip.Data, este estado de uso no es necesario; está aquí sólo para señalarlo.
- Necesitamos referencias a los espacios de nombres de las entidades asociadas a nuestra aplicación, en este caso, Blip.Entities.Customer y Blip.Entitites.Geographies.
- El constructor necesita el nombre exacto de la cadena de conexión que hemos creado previamente, «ApplicationDbContext».
Mantener el contexto de los datos
A medida que se añaden clases de entidades al proyecto Entidades de sus soluciones, es necesario mantener actualizada la lista de entidades en el contexto. En la solución BlipProjects , tenemos tres entidades incluidas en el contexto:
123DbSet<País;PaísesDbSet<Cliente;ClientesDbSet<Región;Regiones
csharp
Tenga en cuenta lo siguiente:
- DbSet es una clase de colección proporcionada por la Entidad Marco namespace System.Data.Entity.
- El tipo de cada colección de DbSet es una de las clases del proyecto de nuestras entidades.
- En BlipProjects nuestra convención es pluralizar el nombre del DbSet y por lo tanto el nombre de la tabla de la base de datos, pero esto no es un requisito.
- Ver objetos modelo como CustomerEditViewModel en Blip.Las entidades no están incluidas porque no se reflejan en la base de datos.
Uso de las migraciones del marco de entidades
El siguiente paso para dar vida a nuestro proyecto de datos es habilitar las migraciones de EF y aplicar una migración inicial para configurar la base de datos. Esto se hace en la ventana de la Consola de Administración de Paquetes (PMC).
Habilitación de Migraciones EF
Las migraciones EF tienen que ser «activadas» en el proyecto en el que serán utilizadas después de añadir el paquete EF NuGet, como hicimos anteriormente.
- Dependiendo de la configuración de inicio de Visual Studio, puede haber una pestaña PMC en la parte inferior de la ventana de Visual Studio. Si hay una ficha de la Consola de administración de paquetes, simplemente haz clic en ella para abrirla.
1![Consola de gestión de paquetes](vs-pkg-mgr-cons_50pct.png)
- Establezca el proyecto por defecto en Blip.Data. Este es un ajuste enormemente importante que debe tener en cuenta para no pasarlo por alto. A Visual Studio le gusta establecer este valor como predeterminado para el inicio o el proyecto web, lo que provocará errores. Está habilitando las migraciones en el proyecto que contiene el contexto de los datos, por lo que este valor debe establecerse en consecuencia antes de ejecutar un comando de Entity Framework.
- En la línea de comandos (PM ), escriba enable-migrations y pulse Intro.
Entity Framework debería tragarse un rato y luego informarle de que se han habilitado las migraciones. Una señal de que el proceso ha funcionado correctamente es la presencia de una carpeta Migraciones bajo la raíz del proyecto de datos en el Explorador de soluciones y un archivo Configuration.cs en esa carpeta. Usaremos ese archivo en el siguiente paso.
Configuración de las migraciones EF
Si sigues la solución de muestra, abre el archivo Configuration.cs . Debería verse así:
123456789101112131415161718192021222324252627282930313233343536373839404142434445espacio de nombres Blip.Data.Migraciones{// usando System;using System.Collections.Generic;// usando System.Data.Entity;usando System.Data.Entity.Migraciones;// usando System.Linq;usando Blip.Entities. Geografías;internalsealedclassConfiguration:DbMigrationsConfiguration<Blip.Data.ApplicationDbContext;;{publicConfiguration(){ AutomaticMigrationsEnabled =false;}protectedoverridevoidSeed(Blip.Data.ApplicationDbContext context){// Este método será llamado después de migrar a la última versión. Puede utilizar/// el método de extensión de ayuda DbSet<T;.AddOrUpdate() para evitar/// la creación de datos de semillas duplicados. var countries =newList<Country{newCountry{ Iso3 ="USA", CountryNameEnglish ="United States of America"},newCountry{ Iso3 ="CAN", CountryNameEnglish ="Canada"},newCountry{ Iso3 ="FRA", CountryNameEnglish ="France"}}; countries. ForEach(s =[; context.Countries.AddOrUpdate(p =[; p.Iso3, s)]); context.SaveChanges();...}}}
csharp
Constructor de la configuración
La clase de configuración se genera automáticamente cuando se activan las migraciones EF. El constructor nos permite establecer una variedad de opciones de configuración para las migraciones EF. Estamos usando una importante configuración que probablemente quieras usar en tus proyectos:
AutomaticMigrationsEnabled = false;
Cuando las migraciones automáticas están activadas, el valor predeterminado de EF, EF creará y aplicará una migración cada vez que realice un cambio en sus entidades que afectará a la estructura de la base de datos. Al principio del desarrollo de una aplicación, las entidades pueden sufrir una serie de cambios, lo que provoca una rápida proliferación de migraciones. Esto debe evitarse.
Con las migraciones automáticas desactivadas, tenemos la oportunidad de decidir cuándo se aplican a la base de datos nuestras modificaciones de las entidades de la aplicación.
Método de la semilla
El método de la semilla nos permite añadir datos a la base de datos cuando se crea. Esto puede ser un gran ahorro de tiempo en dos circunstancias comunes:
- Durante el desarrollo, cuando la base de datos se abandona y se recrea repetidamente a medida que se realizan cambios en el diseño, el método Seed nos permite rellenar las tablas de la base de datos con los datos que utilizaremos durante el desarrollo.
- Durante el despliegue de la aplicación, el método Seed nos permite asegurarnos de que la base de datos se inicialice con un conjunto canónico de datos necesarios para que la aplicación se ejecute.
En nuestro proyecto de datos de ejemplo, Blip.Data , estamos llenando la base de datos con listas de países y regiones.
Algunas notas sobre el uso del método de las semillas:
- El orden de carga de los datos es importante. Debido a que existe una relación padre-hijo entre los países y las regiones, tenemos que rellenar primero la tabla de países. Si no lo hacemos, obtendremos errores de integridad referencial durante la ejecución del T-SQL generado por el método.
- Los errores de sintaxis en la instanciación de instancias de una entidad pueden hacer que los datos se carguen incorrectamente o que no se carguen en absoluto. Cuando se carga un gran número de registros, puede ser útil probar el proceso con unos pocos registros antes de crear una lista larga. El método de la semilla también admite la carga de datos de un archivo externo.
Creación de la base de datos con el Código EF – Migraciones de primera
Ahora que hemos configurado nuestras migraciones EF, estamos listos para crear la base de datos. Eso se hace con una migración inicial .
Creando la migración inicial
Si sigues junto con tu propia versión del proyecto de muestra BlipProjects , sigue estos pasos:
- Configure el campo Proyecto predeterminado de la ventana de la Consola del Administrador de paquetes en: Blip.Data (o como quiera que hayas llamado a tu proyecto de datos).
- Introduzca la siguiente cadena de comandos en el indicador de la Consola del Administrador de paquetes (PM ): add-migration InitialMigration
- Presiona Enter.
Si el comando se ejecuta correctamente, debería crear un nuevo archivo en el directorio Migraciones del proyecto de datos ( Blip.Data ) llamado algo así:
1`201708222251192_InitialMigration.cs`
Este archivo incluirá un método que contiene las instrucciones que EF utiliza para crear la base de datos, junto con otro método que contiene instrucciones para revertir las instrucciones de creación. Cada migración a partir de entonces tendrá un par de métodos comparables.
Actualización de la base de datos
La migración inicial creará la base de datos si no existe ya en la ruta especificada en el connectionString asociado al contexto de los datos. Para aplicar la migración inicial, haga lo siguiente:
- Asegúrate de que el proyecto predeterminado sigue estando configurado en Blip.Data.
- Introduzca la siguiente cadena de comandos en el indicador de la Consola del Administrador de Paquetes (PM ): update-database -verbose -startupprojectname Blip.Data
El argumento -verboso mostrará la salida completa del comando mientras se ejecuta.
Establecer el argumento -StartupProjectName asegura que el comando tiene efecto en el proyecto correcto si el proyecto de inicio es otro proyecto, como la aplicación web (Blip.Web en la solución de muestra).
- Presiona Enter.
Si el proceso se ejecuta correctamente, las primeras líneas de salida en la ventana del PMC se verán algo así:
12345678910111213PM;update-database-verbose -startupprojectname Blip.DataUsing StartUp project $0027Blip.Data$0027.Using NuGet project $0027Blip.Data$0027.Specify the $0027-Verbose$0027 flag toview the SQL statements being applied to the target database.Target databaseis: $0027BlipData$0027(DataSource: (localdb)ProyectosV13, Proveedor: System.Data.SqlClient, Origin: Configuración). Aplicando migraciones explícitas: Aplicando migraciones explícitas: 201708222251192_InitialMigration.CREATETABLE[dbo].[Países]([Iso3][nvarchar](3)NOTNULL, [Nombre del país - inglés][nvarchar](50)NOTNULL,CONSTRAINT[PK_dbo.Países]PRIMARYKEY([Iso3]))...
sql
Tenga en cuenta que tanto el proyecto Startup como el proyecto NuGet están configurados con el nombre del proyecto de datos: Blip.Data. La salida también identifica el servidor de la base de datos y el nombre. A continuación de la información de configuración se encuentra el T-SQL DDL generado a partir de los métodos del archivo de migración.
Si el proceso se completa con éxito, deberías ver:
- La base de datos ha sido creada.
- La tabla de migraciones de la base de datos contendrá un registro con el nombre de la migración.
Creación de métodos de repositorio
Ahora que tienes una base de datos que contiene algunos datos para probar, puedes empezar a desarrollar repositorios. Las clases de repositorios suelen contener métodos para cada una de las funciones de creación, actualización, recuperación y eliminación asociadas a las bases de datos y otros almacenes de datos permanentes, dependiendo del tipo de almacén de datos.
Los tipos de retorno suelen ser objetos individuales o colecciones de objetos basados en modelos de vista o entidades del proyecto de datos. También pueden ser tipos proporcionados por cualquier biblioteca a la que se haga referencia en el proyecto de datos y, según sea necesario, el proyecto que invoque el método de repositorio.
Usando el proyecto de ejemplo Blip.Data , echaremos un vistazo a un par de métodos de repositorio asociados al objeto Customer .
Nuestros repositorios están organizados en una estructura de carpetas y espacios de nombres que corresponden a las entidades que definimos en Blip.Data , pero son posibles muchos otros esquemas organizativos potenciales.
En la carpeta Customer , el archivo CustomerRepository.cs contiene un método para obtener una lista de clientes que se muestra en la vista Index.cshtml . Aquí está la parte superior de ese archivo, incluyendo este método:
12345678910111213141516171819202122232425262728293031323334353637383940414243usando Sistema;usando Sistema.Colecciones.Genéricas;usando Sistema.Datos.Entidad;usando Sistema.Linq;usando Entidades.Blip.Cliente;usando Entidades.Blip.Cliente.VerModelos;espacio de nombres Blip. Datos{clase públicaClientesRepositorio{lista pública<ClienteVistaModelo;GetClientes(){utilizando(var contexto =nuevaAplicaciónDbContexto()){ Lista<Cliente;clientes =nuevaLista<Cliente;Â(); clientes = contexto.Clientes.AsNoTracking(). Include(x = ); x.País).Include(x = ); x.Región).ToList();if(clientes !=null){ List<ClienteDisplayViewModel(); clientesDisplay =newList<ClienteDisplayViewModel(); foreach(var x en clientes){var clienteDisplay =newCustomerDisplayViewModel(){ ClienteID = x. CustomerID, CustomerName = x.CustomerName, CountryName = x.Country.CountryNameEnglish, RegionName = x.Region.RegionNameEnglish }; customersDisplay.Add(customerDisplay);} return clientsDisplay;} returnnnull;}}}
csharp
Tenga en cuenta lo siguiente:
- Las entidades y los modelos de vista del proyecto Blip.Entities se mencionan en las declaraciones de utilización.
- El método GetCustomers() devuelve una colección de listas del objeto modelo de la vista para la vista Index.cshtml. El método Index() del CustomerController del proyecto Blip.Web pasa esta colección a la vista en la que los datos están vinculados al formulario.
- Los elementos de List<CustomerDisplayViewModel
Echa un vistazo a los repositorios en el proyecto de muestra para explorar algunas otras características de los repositorios. La sección de cursos de formación sobre PluralSight relacionados que aparece a continuación tiene enlaces a cursos con más información sobre el patrón de repositorio, incluyendo cómo crear repositorios con Interfaces, lo que facilita las pruebas.