Khi làm việc với Entity Framework (EF), chắc chắn bạn sẽ gặp các khái niệm như Lazy Loading, Eager Loading, hay Explicit Loading. Trong đó, Lazy Loading là một trong những cơ chế quan trọng giúp EF hoạt động linh hoạt hơn trong việc truy xuất dữ liệu liên quan (related data). Tuy nhiên, nếu không hiểu rõ cách nó vận hành, bạn có thể vô tình gây ra bottleneck về hiệu năng, đặc biệt là vấn đề “N+1 Query”.
1. Lazy Loading là gì?
Lazy Loading là cơ chế mà Entity Framework chỉ tải dữ liệu liên quan (navigation properties) khi bạn truy cập tới chúng lần đầu tiên, chứ không tải kèm theo truy vấn ban đầu.

Ví dụ, bạn query thông tin một sinh viên:
var student = context.Students.FirstOrDefault(s => s.Id == 1);
Ở thời điểm này EF chỉ lấy bảng Students, chưa hề lấy địa chỉ, lớp học, hay danh sách khóa học của sinh viên đó.
Chỉ khi bạn gọi:
var address = student.StudentAddress;
Lúc đó EF mới phát sinh một truy vấn SQL khác để lấy dữ liệu.
EF tiếp tục lặp lại hành vi này cho từng navigation property bạn truy cập.
2. Lazy Loading hoạt động như thế nào?
Để Lazy Loading hoạt động, EF tạo một proxy động bao quanh entity, và proxy này sẽ tự động thực thi câu lệnh SQL khi truy cập thuộc tính điều hướng.
Để EF tạo được proxy, cần thỏa mãn:
Navigation property phải là virtual
public virtual StudentAddress StudentAddress { get; set; }
public virtual Standard Standard { get; set; }
public virtual ICollection<Course> Courses { get; set; }
EF phải bật hai cấu hình sau:
Configuration.LazyLoadingEnabled = trueConfiguration.ProxyCreationEnabled = true
(Mặc định đều là true)
3. Ví dụ về Lazy Loading trong thực tế
Giả sử bạn có entity:
public class Student
{
public int StudentId { get; set; }
public string FirstName { get; set; }
public virtual StudentAddress StudentAddress { get; set; }
public virtual Standard Standard { get; set; }
public virtual ICollection<Course> Courses { get; set; }
}
Và bạn chạy đoạn code:
var student = context.Students.FirstOrDefault(s => s.StudentId == 1);
var address = student.StudentAddress;
var standard = student.Standard;
var courses = student.Courses;
Lúc này EF sẽ chạy 4 truy vấn SQL riêng biệt:
- Lấy Student
- Lấy StudentAddress
- Lấy Standard
- Lấy Courses
Đây là hành vi tiêu chuẩn của Lazy Loading.
4. Khi nào không nên dùng Lazy Loading?
Lazy Loading tuy tiện, nhưng có thể gây vấn đề:
N+1 Query Problem
Khi bạn lặp nhiều entity, mỗi entity lại tự phát SQL để tải navigation property.
Ví dụ:
var students = context.Students.ToList();
foreach (var s in students)
{
var address = s.StudentAddress; // mỗi lần sẽ phát 1 SQL
}
Trường hợp bạn có 100 students → phát sinh 101 câu SQL.
Khó kiểm soát SQL sinh ra
Dev mới thường không biết EF đang âm thầm truy vấn DB nhiều lần, dẫn đến hiệu năng kém ở môi trường thật.
Không phù hợp với API (đặc biệt là REST API)
Khi serialize object trả về, JSON serializer có thể trigger Lazy Loading → gây vòng lặp vô hạn hoặc phát SQL không kiểm soát.
5. Khi nào nên dùng Lazy Loading?
Lazy Loading phù hợp nếu:
- Bạn làm ứng dụng nhỏ hoặc CRUD cơ bản
- Dữ liệu liên quan không lớn
- Dữ liệu liên quan chỉ cần nếu người dùng thao tác xem chi tiết
- Không lặp nhiều entity một lúc
Ví dụ: trang web load danh sách sản phẩm, khi click xem chi tiết mới lấy ảnh hoặc thông số — khi đó Lazy Loading là hợp lý.
6. Kết luận
Lazy Loading là một tính năng mạnh mẽ của Entity Framework, giúp bạn tải dữ liệu một cách linh hoạt “khi cần thì lấy”. Tuy nhiên, nếu không dùng đúng cách, nó có thể gây ra những vấn đề nghiêm trọng về hiệu năng, đặc biệt là N+1 Query.
Hãy dùng Lazy Loading khi:
- Dữ liệu liên quan ít
- Không lặp nhiều entity
- Bạn muốn code đơn giản, đọc dễ
Hãy tránh Lazy Loading khi:
- Xây dựng API
- Query danh sách lớn
- Cần kiểm soát SQL chặt chẽ
- Lo ngại hiệu năng
Cuối cùng, hãy nhớ: Lazy Loading là tiện – nhưng không phải lúc nào cũng tốt. Hãy chọn đúng kỹ thuật phù hợp cho từng tình huống.
