Acceso a la Base de Datos usando Entity Framework

Acceso a la Base de Datos usando Entity Framework

Entity Framework es un conjunto de bibliotecas de clases de .NET que permite crear una capa de acceso a datos limpia, portátil y de alto nivel con .NET (C#) en una variedad de bases de datos, como SQL Database (local y Azure), SQLite, MySQL, PostgreSQL y Azure Cosmos DB. Admite consultas LINQ, seguimiento de cambios, actualizaciones y migraciones de esquemas.

Anteriormente y estoy hablando de muchos años atrás, el acceso a la base de datos requería de mucho código que tomara una conexión, una sentencia SQL, recorriera el resultado a traves de un ciclo y con esto nos permitiera mostrar datos. Generalmente era mucho código común y uno terminaba por construir su propia librería para acceso a datos donde iba organizando las cosas comunes en todos los proyectos.

Problemas como:

  • Control de transacciones

  • Manejo de versiones y cambios en las bases de datos

  • Necesidad de cambiar de base de datos

Eran complejos de manejar.

Con el crecimiento de .NET llegó Entity Framework, permitiendo direccionar muchos de estos problemas comunes a los proyectos y trayendo a los desarrolladores la posibilidad de separar el Motor de Bases de Datos de su código.

Nuestro proceso de implementar la base de datos tendrá varias fases:

  1. Instalar Ef Tools

  2. Configuración de la base de datos

  3. Actualización de nuestros Modelos

  4. Creación de un proyecto de acceso a Datos

  5. Registro del proyecto y asociación al WebApi

  6. Creación de Migraciones y Actualización de la base de datos

  7. Ejecución del programa

Instalar Ef Tools

Para interactuar con EntityFramework se cuenta con una poderosa herramienta que hace las tareas desde la consola de comandos, ejecuta el siguiente código

dotnet tool install --global dotnet-ef

Configuración de la base de datos

Podemos tener varios mecanismos para hacerlo:

  • Instalar un Motor de bases de datos Local

  • Usar un servicio en la nube o hosting de bases de datos

  • Usar contenedores

Por facilidad me inclinaré por la primera forma, nos evitará instalar mas software en computador y nos permitirá conocer una herramienta gratuita de Azure bastante interesante.

Usaremos la recien lanzada capa gratuita de SQL Server de Azure disponible en esta ruta

Azure SQL Database free offer - Azure SQL Database | Microsoft Learn

Te invito a registrarte para la capa gratuita de Azure, muchos servicios se mantendrán gratis por siempre y es bastante útil para probar cosas, solo recuerda que lo que uses se mantenga en la capa gratuita.

Otro servicio gratuito, pero para la base de datos Postgres es Neon — Serverless, Fault-Tolerant, Branchable Postgres, también te invito a revisarlo.

Vamos a crear la base de datos

En el Porta del Azure busca el servicio de SQL Server y selecciona SQL Database

Aplica la oferta de capa gratuita

Al terminar de crear la base de datos, Azure nos permitirá generar la cadena de conexión que usaremos en breve.

Recuerda que tambien podrias instalar Docker https://docs.docker.com/desktop/install/windows-install/ y luego configurar una motor de base de datos SQL Server, Postgress o MySQL

Tambien podrías instalar localmente SQL Server Instalar SQL Server 2022 gratis desde cero (y bien) [TUTORIAL] - YouTube (del Canal campusMVP.es)

Actualización de los Modelos

Necesitamos actualizar nuestro proyecto Modelos para hacer las clases mas livianas y buscar adoptarlas a ciertas reglas que Entity Framework posee

Cambia de esta manera las clases EstacionDeServicio y Combustible

namespace Modelos;

public class EstacionDeServicio
{
    public int EstacionDeServicioId { get; set; }
    public List<Combustible> Combustibles { get; set; }
    public bool EstaAbierta { get; set; }
    public string Direccion { get; set; } 
}
namespace Modelos;

public class Combustible
{
    public int CombustibleId { get; set; }
    public string TipoCombustible { get; set; }
    public double CostoGalon { get; set; }

    public EstacionDeServicio EstacionDeServicio { get; set; }
}

Aunque parezca curioso, estos cambios aún no afectan el funcionamiento de nuestro código. Vamos al siguiente paso.

Creación de un proyecto de acceso a datos

Vamos a crear en la misma carpeta de la solución un nuevo proyecto, recuerda darle una mirada a la publicación anterior si no recuerdas como.

Con esta linea crearás el proyecto

dotnet new classlib -n AccesoADatos

Con esta asociarás los modelos

dotnet add .\AccesoADatos\AccesoADatos.csproj reference .\Modelos\Modelos.csproj

Ahora debemos instalar Entity Framework en nuestro proyecto, vamos a usar la linea de comandos para hacerlo mas sencillo. La primera instrucción nos mueve al proyecto AccesoADatos, la segunda instala Entity Framework

cd .\AccesoADatos\
dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer

Con esto el proyecto está listo para crear una pieza de código fundamental en EntityFramework: El DbContext. Esta es una clase que nos permite servir de intermediario entre la Base de datos y nuestro código

Crea un archivo en el proyecto AccesoADatos, que se llame EstacionesDbContext.cs

using Microsoft.EntityFrameworkCore;
using Modelos;

namespace AccesoADatos;

public class EstacionesDbContext : DbContext
{

    public DbSet<EstacionDeServicio> EstacionDeServicio { get; set; } = null!;
    public DbSet<Combustible> Combustible { get; set; } = null!;

    public EstacionesDbContext(DbContextOptions<EstacionesDbContext> options)
        : base(options)
    {
    }

}

Este código relaciona dos propiedades para hacer referencia a las dos clases de Modelos que creamos, por ahora no entraremos en más detalle, pero tendremos en los siguientes días un video profundizando sobre esto.

Registro del proyecto y asociación al WebApi

Al proyecto WebApi debemos agregar la referencia al nuevo proyecto

dotnet add .\WebApi\WebApi.csproj reference .\AccesoADatos\AccesoADatos.csproj

Vamos a tomar la cadena de conexión y la llevaremos a nuestro proyecto. En el portal de Azure podemos ver la cadena de conexión

Ahora debemos configurar en nuestro proyecto la cadena de conexión la base de datos y para hacerlo debemos modificar el archivo appsettings.Development.json para que se vea de la siguiente forma:

{
  "ConnectionStrings": {
    "DbConnection":"Server={tuservidor};Initial Catalog={tubasededatos};Persist Security Info=False;User ID={tuusuario};Password={tupassword};MultipleActiveResultSets=True;Encrypt=True;TrustServerCertificate=True;Connection Timeout=30;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  }
}

Casi llegamos al final...

Se hace necesario instalar el proveedor de SQL Server para EntityFramework

cd .\WebApi\
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Design

La primera instrucción nos mueve al proyecto WebApi

La segunda instala el proveedor de SQL Server para EntityFramework

La tercera instala las librerias para implementar migraciones y actualizar nuestra base de datos

Ahora uniremos las piezas y por el momento será en el Program.cs, donde vamos a tener lo siguiente:

  • Inyectaremos a los servicios del WebApi el contexto

  • Asociaremos el Contexto a la Base de Datos

  • Actualizaremos los Controladores de MinimalApi

Revisa atentamente los comentarios en el siguiente código, reemplaza completamente tu Program.cs por el siguiente

// Permitimos usar las clases de los proyectos Modelos y Servicios
using Modelos;
using Servicios;
using AccesoADatos;
//Importamos el Proveedor de Ef Core para SQL Server
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.SqlServer;

var builder = WebApplication.CreateBuilder(args);

//Configurar el contexto de la base de datos 
//Esta linea Toma del archivo appsettings.json la cadena de conexion
//y la pasa al contexto de la base de datos
//Ademas configura que se use SQL Server
builder.Services.AddDbContext<EstacionesDbContext>(options =>
{
    options.UseSqlServer(builder.Configuration.GetConnectionString("DbConnection"));
});

// Adicionamos el servicio de la base de datos de estaciones
// para que este disponible en toda la aplicacion y pueda llamarse en los servicios
// Esto es un singleton, es decir, solo se crea una vez y se usa en toda la aplicacion
// Se deshabilita porque ya no es necesaria - puedes borrarla
//builder.Services.AddSingleton<BdEstaciones>();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

//Se obtiene el listado de estaciones
//Se usa el contexto de la base de datos
app.MapGet("/estaciones", (EstacionesDbContext bd) =>
{
    var estaciones = bd.EstacionDeServicio.ToList();
    return estaciones;
})
.WithName("ListaEstaciones")
.WithOpenApi();

//Se agrega una estacion
//Observa que tambien se usa el contexto de la base de datos
app.MapPost("/estaciones", (EstacionesDbContext bd, EstacionDeServicio estacion) =>
{
    //Se agrega el objeto estacion al contexto de la base de datos    
    bd.Add(estacion);
    //Se guardan los cambios en la base de datos
    bd.SaveChanges();

    return estacion;
})
.WithName("AgregarEstacion")
.WithOpenApi();

app.Run();

En este punto solo nos falta indicarle a la base de datos SQL Server que debe crear las tablas que planeamos en los objetos del proyecto Modelos.

A este proceso lo llamamos Migraciones y es la forma de EntityFramework de ejecutar cambios en la base de datos, hacerlo es sencillo.

En la consola, estando en la carpeta del WebApi ejecuta este comando

dotnet ef migrations add M1 -c EstacionesDbContext -p ..\AccesoADatos\

Esto comando hace "por debajo" muchas cosas, si vas y miras el proyecto AccesoADatos tendrá nuevo contenido, vale la pena darle una mirada.

Ahora actualizaremos nuestra base de datos, pues hasta ahora hemos configurado todo, pero no hemos enviado nada a la base de datos, para hacerlo ejecutemos el siguiente comando

dotnet ef database update -c EstacionesDbContext -p ..\AccesoADatos\

Esto generará que EntityFramework envíe al servidor SQL los comandos necesarios para crear las tablas según nuestros modelos creados.

¿Estamos listos? Pues ejecutemos la aplicación y veamos como funciona

Como hicimos en la publicación pasada, ejecuta el método POST con el siguiente contenido

{ 
  "combustibles": [
    { 
      "tipoCombustible": "Diesel",
      "costoGalon": 15000
    }
  ],
  "estaAbierta": true,
  "direccion": "Calle 1 # 1 - 1"
}

Ahora tendremos listo nuestro servicio conectado a la Base de datos.

¿sencillo? posiblemente muchas cosas aún quedan en el aire, pero es normal, estamos construyendo esto muy rápido, pero bueno luego lo profundizamos.

Si algo te falla o quieres una sesión de ayuda personalizada (Gratuita por supuesto), déjamelo saber, estaré muy feliz de apoyar.