Los dos caminos del Database First en Entity Framework Core 2.0

La técnica database first o base de datos primero, nos permite tomar una base de datos ya existente, y a partir de ella generar todos los modelos y el dbContext para poder utilizar Entity Framework Core con dicha base de datos. Esto es ideal cuando tienes una base de datos ya creada, y quieres utilizar Entity Framework Core con ella.

Tenemos dos alternativas para utilizar database first en Entity Framework Core 2. La primera alternativa es que generemos los modelos y el dbContext, y entonces activemos las migraciones, esto significa que podremos hacer cambios sobre nuestra base de datos a partir de nuestro código de c#, y podremos guardar un histórico de dichos cambios a través de las migraciones. La segunda alternativa es que luego de que generemos los modelos y el dbContext a partir de la base de datos, no activemos las migraciones, sino que simplemente actualicemos los modelos y el dbcontext para que reflejen cualquier cambio que se haga sobre la base de datos en el futuro. Vamos a ver ejemplos de estas dos vías, pero primero, vamos a hacer database first con Entity Framework Core 2.

En esta entrada, vamos a trabajar con Visual Studio 2017, Entity Framework Core 2.0 y con SQL Server, aunque nada te detiene para aplicar esto con otros motores de bases de datos, como MySQL.

Haciendo el database first

Lo primero que necesitamos es un proyecto de .net. Yo voy a crear una aplicación web con .net Core 2, pero cualquier proyecto que soporte Entity Framewok Core 2 funciona para lo que vamos a hacer.

Para hacer el database first lo primero que necesitamos es una base de datos. Luego de tener la base de datos y el proyecto de .net, vamos a utilizar el tooling de Entity Framework Core para generar los modelos y el dbContext que trabajan con nuestra base de datos. Para esto usaremos el comando Scaffold-DbContext.

Scaffold-DbContext

El comando Scaffold-DbContext es con el que podemos hacer database first. Este comando nos permite tomar una base de datos y generar los modelos que representan sus tablas y el dbContext con las configuraciones de lugar. Lo mínimo que necesitamos para utilizarlo es:

– El connectionString (cadena de conexión) que apunta a la base de datos
– El proveedor que indica el motor de base de datos que estás utilizando. En nuestro caso, utilizaremos el proveedor estándar de SQL Server.

Existen otros parámetros que podemos utilizar en el Scaffold-DbContext. Uno de ellos es para indicar en qué directorio o carpeta colocaremos los modelos y dbContext generados a partir de la base de datos. Otro parámetro es para indicar las tablas las cuales quieres generar, por defecto, se generan todas. En nuestro caso generaremos todas las tablas y colocaremos los archivos en la carpeta Models.

Al final, mi comando va a ser el siguiente:

Scaffold-DbContext “Data Source=MY_SERVER;Initial Catalog=MY_DATABASE;Integrated Security=True” Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

Este comando lo debes colocar en el Package Manager Console. En Visual Studio 2017 esta ventana la puedes encontrar en Tools > Nuget Package Manager > Package Manager Console.

Luego del Scaffold-DbContext tenemos el connectionString. Más adelante colocamos el proveedor, y por último, con -OutputDir Models, indicamos que queremos que los modelos generados se guarden en el directorio o carpeta Models.

Ya con esto, hemos utilizado database first, sin embargo, rara vez esto es el final, habrán ocasiones en las que vas a querer hacer cambios a la base de datos, ya sea desde el código de C# (por ejemplo: Agregar nuevas tablas, nuevas columnas, etc.); o ya sea que actualices la base de datos a través del SQL Server Management Studio, y necesites que tu código de C# reconozca esos cambios. Estos son los dos caminos a seguir posterior a hacer el database first. Vamos a ver cómo implementar cada uno.

Camino 1 – Activando migraciones después de hacer el database first

Si luego de hacer el database first quieres activar las migraciones, pues:

– Quieres hacer cambios a tu base de datos con Entity Framework
– Quieres mantener un histórico de los cambios que hagas

Entonces este es el camino que debes tomar.

Solo debes seguir los siguientes pasos para configurar correctamente las migraciones en este escenario:

Paso 1 – Ve al Package Manager Console.

Paso 2 – Utiliza el comando “Add-Migration Initial

Paso 3 – Utiliza el comando “Script-Migration“. Esto va a generar un script de SQL con los cambios de la migración

Paso 4 – Copia el Create Table de __EFMigrationHistory y el Insert que se va a hacer sobre la misma tabla


IF OBJECT_ID(N'__EFMigrationsHistory') IS NULL
BEGIN
CREATE TABLE [__EFMigrationsHistory] (
[MigrationId] nvarchar(150) NOT NULL,
[ProductVersion] nvarchar(32) NOT NULL,
CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId])
);
END;

GO

INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion])
VALUES (N'20180322234456_inicial', N'2.0.1-rtm-125'); /*Estos valores pueden ser diferentes en tu caso*/

GO

Paso 5 – Pega los queries en SQL Server Management Studio

Paso 6 – Ejecuta los queries. Esto hará que Entity Framework piense que ya hemos aplicado la migración.

Ya con esto, tienes las migraciones activadas y puedes continuar con tu proyecto como si fuera de Code First, es decir, puedes hacer cambios a tus modelos y dbContext, puedes luego hacer migraciones de estos cambios, y empujarlos a la base de datos.

Si esto no es exactamente lo que quieres, si lo que quieres es no utilizar migraciones, y quieres que tu proyecto asuma los cambios de la base de datos de otra manera, el camino 2 deberás tomar.

Camino 2 – Actualizando los modelos y dbContext sin migraciones

Si luego de hacer tu database first quieres que tus modelos y dbContext reflejen nuevos cambios de la base de datos, tienes al menos dos maneras de proceder:

a) Puedes realizar los cambios a mano en tus modelos. Por ejemplo, si agregaste una columna en una tabla, entonces puedes ir al modelo, y agregar una propiedad correspondiente. Esto requiere que sepas hacer las configuraciones adecuadas de Entity Framework. La ventaja de hacerlo de esta forma es que, si son pocos cambios, lo puedes hacer rápidamente sin tener que perder cambios que hayas realizado en tus modelos y DbContext posterior al haber realizado el database first. La desventaja es que puede ser tedioso y debes tener cuidado de no equivocarte, o podrías tener una excepción en tiempo de ejecución.

b) Puedes volver a hacer el Scaffold-DbContext para traer los cambios de la base de datos a tu proyecto. La ventaja de esto es que es fácil. La desventaja es que pierdes cualquier cambio que hayas hecho a los modelos y al dbContext. Por ejemplo, si del DbContext tomaste el connectionString y lo colocaste en un archivo externo, cuando hagas el Scaffold-DbContext de nuevo, vas a perder ese cambio, y tendrás que volver a hacerlo. Esto quizás no sea tan malo, porque las bases de datos no tienden a cambiar demasiado una vez el proyecto es estable.

Conclusión

Cuando hacemos Database First para generar el DbContext y modelos a partir de una base de datos para poder utilizar Entity Framework, tenemos varias opciones para trabajar en lo adelante. Una de ellas es activar las migraciones y hacer cambios de a tu base de datos desde tu proyecto utilizando “Code First”. Otra opción es que luego de que los cambios sean realizados en la base de datos, actualicemos manualmente los modelos y DbContext del proyecto, o que volvamos a correr el comando Scaffold-DbContext.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s