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:
Instalar Ef Tools
Configuración de la base de datos
Actualización de nuestros Modelos
Creación de un proyecto de acceso a Datos
Registro del proyecto y asociación al WebApi
Creación de Migraciones y Actualización de la base de datos
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.