Include y ThenInclude
Include
y ThenInclude
son métodos de carga adelantada (Eager Loading) en Entity Framework Core que te permiten recuperar datos relacionados junto con la entidad principal. Include
se utiliza para cargar una entidad relacionada directa, mientras que ThenInclude
se utiliza para cargar entidades relacionadas adicionales en una cadena de relaciones. A continuación, te proporcionaré varios ejemplos para ilustrar su uso.
Supongamos que tienes las siguientes entidades:
public class Student
{
public int StudentId { get; set; }
public string Name { get; set; }
public ICollection<Course> Courses { get; set; }
}
public class Course
{
public int CourseId { get; set; }
public string CourseName { get; set; }
public int TeacherId { get; set; }
public Teacher Teacher { get; set; }
}
public class Teacher
{
public int TeacherId { get; set; }
public string TeacherName { get; set; }
}
1. Carga Simple con Include
:
using (var context = new SchoolContext())
{
var studentsWithCourses = context.Students
.Include(s => s.Courses)
.ToList();
}
En este ejemplo, se cargarán los cursos asociados con cada estudiante.
2. Carga Adicional con ThenInclude
:
using (var context = new SchoolContext())
{
var studentsWithCoursesAndTeachers = context.Students
.Include(s => s.Courses)
.ThenInclude(c => c.Teacher)
.ToList();
}
En este ejemplo, además de cargar los cursos, también se cargarán los profesores asociados con cada curso.
3. Carga Múltiple con ThenInclude
:
using (var context = new SchoolContext())
{
var studentsWithCoursesAndTeachersAndDetails = context.Students
.Include(s => s.Courses)
.ThenInclude(c => c.Teacher)
.Include(s => s.OtherDetails)
.ToList();
}
En este ejemplo, se cargan los cursos y profesores asociados, así como cualquier otro detalle relacionado con cada estudiante.
4. Carga Condicionada con Include
:
using (var context = new SchoolContext())
{
var studentsWithSpecificCourses = context.Students
.Include(s => s.Courses.Where(c => c.CourseName.Contains("Math")))
.ToList();
}
En este ejemplo, se cargarán solo los cursos que contienen la palabra “Math”.
5. Carga de Varios Niveles con ThenInclude
:
using (var context = new SchoolContext())
{
var studentsWithCoursesAndTeachersAndDepartments = context.Students
.Include(s => s.Courses)
.ThenInclude(c => c.Teacher)
.ThenInclude(t => t.Department)
.ToList();
}
En este ejemplo, se carga la información de cursos, profesores y departamentos relacionados.
Aquí tienes ejemplos de consultas en LINQ con Entity Framework Core
(EF Core) para relaciones uno a muchos y muchos a muchos. Imaginemos que tienes tres entidades relacionadas: Author
, Book
, y Category
. La relación es la siguiente:
- Uno a muchos entre
Author
yBook
(un autor puede tener varios libros, pero un libro tiene un solo autor). - Muchos a muchos entre
Book
yCategory
(un libro puede pertenecer a varias categorías y una categoría puede incluir varios libros).
Ejemplo de Clases
public class Author
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Book> Books { get; set; }
}
public class Book
{
public int Id { get; set; }
public string Title { get; set; }
public int AuthorId { get; set; }
public Author Author { get; set; }
public ICollection<Category> Categories { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Book> Books { get; set; }
}
Consultas Uno a Muchos (One-to-Many)
1. Obtener todos los libros con su autor
var booksWithAuthors = context.Books.Include(b => b.Author).ToList();
2. Filtrar autores que tengan más de 3 libros
var authorsWithMoreThanThreeBooks = context.Authors
.Where(a => a.Books.Count > 3)
.ToList();
3. Obtener todos los libros de un autor específico por su Id
var authorBooks = context.Books
.Where(b => b.AuthorId == authorId)
.ToList();
4. Contar el número de libros por autor
var booksCountByAuthor = context.Authors
.Select(a => new { AuthorName = a.Name, BooksCount = a.Books.Count })
.ToList();
Consultas Muchos a Muchos (Many-to-Many)
1. Obtener todos los libros junto con sus categorías
var booksWithCategories = context.Books
.Include(b => b.Categories)
.ToList();
2. Obtener todas las categorías junto con sus libros
var categoriesWithBooks = context.Categories
.Include(c => c.Books)
.ToList();
3. Obtener todos los libros de una categoría específica
var booksInCategory = context.Categories
.Where(c => c.Id == categoryId)
.SelectMany(c => c.Books)
.ToList();
4. Obtener todas las categorías de un libro específico
var categoriesForBook = context.Books
.Where(b => b.Id == bookId)
.SelectMany(b => b.Categories)
.ToList();
Consultas Avanzadas Combinadas
1. Obtener autores que tienen libros en una categoría específica
var authorsInCategory = context.Authors
.Where(a => a.Books.Any(b => b.Categories.Any(c => c.Id == categoryId)))
.ToList();
2. Obtener categorías que contengan libros de un autor específico
var categoriesForAuthor = context.Categories
.Where(c => c.Books.Any(b => b.AuthorId == authorId))
.ToList();
3. Listar cada autor con los nombres de las categorías en las que se encuentran sus libros
var authorsWithCategories = context.Authors
.Select(a => new
{
AuthorName = a.Name,
Categories = a.Books
.SelectMany(b => b.Categories)
.Select(c => c.Name)
.Distinct()
.ToList()
})
.ToList();
Estas consultas abarcan diferentes combinaciones que suelen aplicarse en casos de relaciones uno a muchos y muchos a muchos usando EF Core y LINQ.
https://www.entityframeworktutorial.net/efcore/querying-in-ef-core.aspx
https://learn.microsoft.com/en-us/ef/core/querying/related-data/eager