entity-framework-configuracion-dbcontext

Qué es y cómo usar DbContext en Entity Framework

  • 4 min

En este tutorial vamos a explorar el objeto DBContext, que representa el componente central de Entity Framework y actúa como puente entre nuestra aplicación .NET y la base de datos subyacente.

El DBContext es la clase principal que nos permite interactuar con la base de datos sin escribir SQL directamente, proporcionando los métodos para realizar operaciones de lectura, escritura, actualización y eliminación de datos.

Características principales

  • Permite definir el modelo de datos mediante propiedades DbSet<T>
  • Se encarga de gestionar las conexiones con la base de datos
  • Permite realizar consultas a la base de datos utilizando LINQ
  • Ofrece métodos para gestionar el ciclo de vida de las entidades

En otras palabras, es la clase más importante y el núcleo de Entity Framework, ya que es la que nos permite interactuar con la base de datos sin necesidad de escribir SQL manualmente.

Configuración básica del DbContext

Para usar la clase DbContext generalmente creamos una clase que hereda de ella, en la que definimos qué tablas (entidades) estarán asociadas a nuestra base de datos.

Dentro de nuestra clase DbContext (que hereda de ella)

  • Definiremos propiedades de tipo DbSet<T>, que representan las tablas en la base de datos.
  • Cada DbSet<T> permite interactuar con la tabla asociada, donde T es el tipo de la entidad (por ejemplo, User o Product).

Vamos a verlo con un ejemplo,

using Microsoft.EntityFrameworkCore;

public class MiContexto : DbContext
{
    // Representa la tabla "Productos" en la base de datos
    public DbSet<Producto> Productos { get; set; }

    // Representa la tabla "Clientes" en la base de datos
    public DbSet<Cliente> Clientes { get; set; }
}

En este ejemplo,

  • Hemos creado una clase llamada MiContexto que hereda de DbContext
  • Dentro de esta clase, hemos definido dos propiedades DbSet: Productos y Clientes
    • Estas propiedades representan las tablas de la base de datos.

Configurar la conexión a la base de datos

El DbContext necesita saber cómo conectarse a la base de datos. Tenemos varias formas de pasarle la configuración,

En aplicaciones donde no tenemos un servicio de inyección de dependencias (típicamente aplicaciones de consola o escritorio) podemos usar el método OnConfiguring para establecer la configuración

public class MiContexto : DbContext
{
    public DbSet<Producto> Productos { get; set; }
    public DbSet<Cliente> Clientes { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
	    const string connectionString = Configuration.GetConnectionString("DefaultConnection");

        // Configura la conexión a SQL Server
        optionsBuilder.UseSqlServer(connectionString);
    }
}

En este ejemplo, hemos sobrescrito el método OnConfiguring para especificar la cadena de conexión a SQL Server.

En aplicaciones ASP.NET Core, lo habitual y recomendable recomendable utilizar la inyección de dependencias para configurar el DbContext.

Generalmente esto lo configuraremos en el fichero Program.cs de la aplicación, usando el método AddDbContext del contenedor de servicios,

const string connectionString = Configuration.GetConnectionString("DefaultConnection");

// Configura el DbContext para usar SQL Server
services.AddDbContext<MiContexto>(options =>
    options.UseSqlServer(connectionString)
);

En algunas aplicaciónes, el alcance de inyección de dependencias no coincide con la vida útil deseada del DbContext (por ejemplo, en Blazor, donde la conexión es persistente, no por solicitud).

En este caso podemos registrar una factoria, que puede crear nuevas instancias de DbContext bajo demanda,

services.AddDbContextFactory<MiContexto>(options => 
    options.UseSqlServer(connectionString);

Después, los servicios que usen la factoría podrían crear un nuevo DbContext haciendo

MiContexto context = _contextFactory.CreateDbContext()

Uso adecuado del ciclo de vida

El DbContext debe tener un ciclo de vida limitado. Normalmente configura como Scoped en el contenedor de DI, lo que asegura que se crea una instancia por cada solicitud HTTP

Operaciones comunes con el DbContext

Ahora que tenemos configurado nuestro DbContext y hemos definido las clases con DbSet ya podríamos hacer operaciones con ella.

Por ejemplo, veamos algunas de las operaciones básicas CRUD (Create Read Update y Delete)

El método Add o AddRange se utiliza para insertar nuevas entidades en la base de datos:

var newUser = new User { Name = "Luis Llamas", Email = "[email protected]" };
_context.Users.Add(newUser);
await _context.SaveChangesAsync();

Las consultas se realizan mediante LINQ:

var user = await _context.Users
    .FirstOrDefaultAsync(u => u.Email == "[email protected]");

Modifica los datos en memoria y guarda los cambios:

var user = await _context.Users.FindAsync(1);
if (user != null)
{
    user.Name = "Luis Updated";
    await _context.SaveChangesAsync();
}

Elimina entidades usando Remove:

var user = await _context.Users.FindAsync(1);
if (user != null)
{
    _context.Users.Remove(user);
    await _context.SaveChangesAsync();
}

¿A que es fácil? ¡Pero hay mucho más! Iremos viendo todos estos elementos en profundidad en los próximos tutoriales.