Inicio > Cursos > C# > Entity Framework Core
C#C# ModernoLección 19 de 20

Entity Framework Core

Entity Framework Core (EF Core) es el ORM oficial de .NET. Un ORM mapea clases C# a tablas de base de datos: en vez de escribir SQL manual, trabajas con objetos. Defines una clase Producto con propiedades y EF Core crea la tabla con columnas correspondientes. Las relaciones entre tablas se expresan con propiedades de navegación: una propiedad List<Producto> en Categoria crea automáticamente la relación 1:N.

El enfoque Code-First significa que el código dicta la estructura de la DB. Cuando cambias una clase (agregas una propiedad, cambias un tipo), creas una "migración" con dotnet ef migrations add NombreCambio. Esto genera un archivo C# con las instrucciones SQL necesarias. dotnet ef database update aplica los cambios a la DB. Este flujo permite versionar la estructura de la base de datos junto con el código en Git.

// 1. MODELOS — Las clases son las tablas
public class Categoria {
    public int Id { get; set; }
    public string Nombre { get; set; } = "";
    public List<Producto> Productos { get; set; } = new(); // 1:N
}

public class Producto {
    public int Id { get; set; }
    public string Nombre { get; set; } = "";
    public decimal Precio { get; set; }
    public int Stock { get; set; }
    public int CategoriaId { get; set; }      // FK
    public Categoria Categoria { get; set; }   // Navegación
}

// 2. DBCONTEXT — Configura la DB
public class TiendaDb : DbContext {
    public TiendaDb(DbContextOptions<TiendaDb> opts) : base(opts) {}
    public DbSet<Producto> Productos => Set<Producto>();
    public DbSet<Categoria> Categorias => Set<Categoria>();

    protected override void OnModelCreating(ModelBuilder mb) {
        mb.Entity<Producto>()
          .Property(p => p.Precio)
          .HasPrecision(10, 2);
        mb.Entity<Producto>()
          .HasIndex(p => p.Nombre);
    }
}

// 3. CONSULTAS con LINQ
async Task Ejemplos(TiendaDb db) {
    // Crear
    var cat = new Categoria { Nombre = "Electrónica" };
    db.Categorias.Add(cat);
    await db.SaveChangesAsync();

    // Leer con include (JOIN)
    var productos = await db.Productos
        .Include(p => p.Categoria)
        .Where(p => p.Precio < 100)
        .OrderBy(p => p.Nombre)
        .ToListAsync();

    // Actualizar
    var prod = await db.Productos.FindAsync(1);
    if (prod != null) {
        prod.Precio = 99.99m;
        await db.SaveChangesAsync();
    }

    // Consulta compleja con agrupación
    var resumen = await db.Productos
        .GroupBy(p => p.Categoria.Nombre)
        .Select(g => new {
            Categoria = g.Key,
            Total = g.Count(),
            PromedioPrecios = g.Average(p => p.Precio)
        })
        .ToListAsync();
}

// MIGRACIONES en terminal:
// dotnet ef migrations add CrearTablas
// dotnet ef database update
// dotnet ef migrations add AgregarStock
Consejo🔄 Flujo Code-First: cambias la clase C# → creas migración (dotnet ef migrations add) → aplicas a la DB (dotnet ef database update). La DB siempre refleja tu código.
← Pattern Matching y ExpresionesProyecto: API con ASP.NET Core →

Practica esta lección

Resuelve los ejercicios del curso de C# en la app, gratis y con corrección automática.

Empezar a practicar