Database First en Entity Framework Core

Este post trata sobre cómo utilizar el enfoque "Database First" en Entity Framework Core. Para aquellos de ustedes que no estén familiarizados con Entity Framework, se trata de un marco de trabajo de Microsoft que facilita la creación de aplicaciones de bases de datos como vimos en uno de los posts anteriores.

 

 

1 - Qué es database first?

El enfoque Database First significa que primero se crea la base de datos y luego se genera el modelo de Entity Framework Core a partir de ella. Esto puede ser útil cuando ya se tiene una base de datos existente o cuando se desea tener un mayor control sobre la estructura de la base de datos.

 

2 - Implementar Database First con Entity Framework Core

Antes de ir a la propia implementación quiero decir que vamos a utilizar la base de datos MySQL a través de docker, pero que este enfoque funciona con cualquier base de datos relacional, el único cambio es, además de la propia sintaxis en los scripts, la connection string en el código C#. 

El resto debería ser agnóstico a la base de datos. 

 

Para ello, lo primero que vamos a hacer es crear la base de datos, en este caso es simple, un par de tablas con una relación entre ellas

CREATE DATABASE IF NOT EXISTS `cursoEF`;
USE `cursoEF`;


CREATE TABLE IF NOT EXISTS `userid` (
  `UserId` int(11) NOT NULL AUTO_INCREMENT,
  `UserName` varchar(50) NOT NULL,
  PRIMARY KEY (`UserId`),
  UNIQUE KEY `UserName` (`UserName`)
);


CREATE TABLE IF NOT EXISTS `wokringexperience` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `UserId` int(11) NOT NULL,
  `Name` varchar(150) NOT NULL,
  `Details` varchar(5000) NOT NULL,
  `Environment` varchar(500) NOT NULL,
  `StartDate` date DEFAULT NULL,
  `EndDate` date DEFAULT NULL,
  PRIMARY KEY (`id`),
  FOREIGN KEY (`UserId`) REFERENCES `userid`(`UserId`)
);

Y si te conectas con una interfaz de usuario, esto es lo que deberías de poder ver:

sql ejecutado

 

2.1 - Importar las entidades de una base de datos con Entity Framework Core

Para comenzar, primero debemos tener una aplicación creada, en mi caso es una Web API (disponible en GitHub) y le debemos instalar el paquete Microsoft.EntityFrameworkCore.Design.

El cual lo podemos añadir de forma manual, o con el siguiente comando:

dotnet add package Microsoft.EntityFrameworkCore.Design

 

En mi caso particular utilizo mysql, por lo que tengo que añadir, además, el paquete de MySQL:

dotnet add package MySql.EntityFrameworkCore

 

Si estás utilizando otra base de datos, como mariaDB o SQL Server, los paquetes a instalar son diferentes, te recomiendo que mires la documentación.

 

 

Una vez el proceso ha terminado, lo que vamos a querer hacer es importar las tablas de la base de datos como entidades, y para ello corremos el comando scaffold de entity framework core:

dotnet ef dbcontext scaffold "server=127.0.0.1;port=3306;database=cursoEF;user=cursoEFuser;password=cursoEFpass" MySql.EntityFrameworkCore -o Models

En mi caso estoy ejecutándolo con el usuario que he indicado, pero puedes poner la string de conexión que corresponda a tu base de datos. 

Finalmente la opción -o Models indica donde irán ubicadas las clases generadas por la herramienta.

Cuando termina, podemos ver algo así:

Como podemos ver nos crea tanto el DBContext que representa a la base de datos como un DBSet para cada una de las tablas. 

 

Por ejemplo esta es la entidad que nos ha generado para representar la tabla userId

public partial class Userid
{
    public int UserId1 { get; set; }

    public string UserName { get; set; } = null!;

    public virtual ICollection<Wokringexperience> Wokringexperiences { get; } = new List<Wokringexperience>();
}

 

 

3 - Mejorar la implementación por defecto de Entity Framework

Por defecto, la conexión a la base de datos nos viene dentro de nuestro DBContext y esto lo tenemos que cambiar, porque no es seguro, de hecho, viene con un warning por defecto.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
    => optionsBuilder.UseMySQL("server=127.0.0.1;port=4306;database=cursoEF;user=cursoEFuser;password=cursoEFpass");

Lo que debemos hacer configurar nuestro DBContext dentro de nuestro contenedor de dependencias, que dependiendo en qué versión de .NET estés, estará en la clase startup.cs o en program.cs además idealmente la conexión deberá estar en el fichero de configuración para poder utilizar Iconfiguration o incluso mejor, en un vault de gestión de credenciales. El código nos quedará algo así:

builder.Services.AddDbContext<CursoEfContext>(options =>
    options.UseMySQL(builder.Configuration.GetConnectionString("cursoEF") 
                     ?? throw new Exception("missing connectionstring")));

Y esta acción nos permite eliminar el método Onconfiguring de nuestro DBContext

 

 

4 - Ejemplo de aplicación C# con Entity Framework

Ahora solo nos queda probar la app, para este ejemplo voy a hacer un código sencillo, voy a ejecutar todo desde el controlador, si ves mi canal sabes que nunca recomiendo hacer esto, pero para una prueba de concepto, pues es aceptable.

 

Pero para este caso, simplemente vamos a tener un endpoint para insertar los datos:

[ApiController]
[Route("[controller]")]
public class CursoEFController : ControllerBase
{
    private readonly CursoEfContext _context;

    public CursoEFController(CursoEfContext context)
    {
        _context = context;
    }

    [HttpPost]
    public async Task<int> AddUser(UserDto userDto)
    {
        Userid user = new Userid()
        {
            UserName = userDto.UserName
        };

        await _context.Userids.AddAsync(user);
        await _context.SaveChangesAsync();
        
        return user.UserId1;
    }
}

public record UserDto(string UserName);

Y podemos ver el resultado:

insercion con entity framework core

Recuerda que para hacer acciones CRUD puedes utilizar LINQ sobre el DBSet

 

 

5 - Actualizar el modelo utilizando Database First en EF Core

Para actualizar el modelo, osea las clases de C# dentro de nuestro proyecto cuando la estructura de la base de datos es actualizada debemos ejecutar el mismo comando que para hacer la ejecución inicial, únicamente incluyendo la opción --force

dotnet ef dbcontext scaffold "server=127.0.0.1;port=3306;database=cursoEF;user=cursoEFuser;password=cursoEFpass" MySql.EntityFrameworkCore -o Models --force

Y con esto finalizamos la parte de Database First, donde tenemos la base de datos ya creada cuando empezamos a desarrollar. 

 


Uso del bloqueador de anuncios adblock

Hola!

Primero de todo bienvenido a la web de NetMentor donde podrás aprender programación en C# y .NET desde un nivel de principiante hasta más avanzado.


Yo entiendo que utilices un bloqueador de anuncios como AdBlock, Ublock o el propio navegador Brave. Pero te tengo que pedir por favor que desactives el bloqueador para esta web.


Intento personalmente no poner mucha publicidad, la justa para pagar el servidor y por supuesto que no sea intrusiva; Si pese a ello piensas que es intrusiva siempre me puedes escribir por privado o por Twitter a @NetMentorTW.


Si ya lo has desactivado, por favor recarga la página.


Un saludo y muchas gracias por tu colaboración

© copyright 2023 NetMentor | Todos los derechos reservados | RSS Feed

Buy me a coffee Invitame a un café