EF 6 - Eager Loading
Eager Loading trong Entity Framework
Eager Loading là gì?
Eager Loading là quá trình trong đó một truy vấn cho một kiểu thực thể cũng tải các thực thể liên quan như một phần của truy vấn, do đó chúng ta không cần phải thực hiện một truy vấn riêng cho các thực thể liên quan.
Eager Loading được thực hiện bằng cách sử dụng phương thức Include()
.
Trong ví dụ sau sẽ lấy Student có tên "Bill" từ cơ sở dữ liệu kèm theo thông tin Standard của nó bằng phương thức Include()
.
Cú pháp truy vấn LINQ:
using (var context = new SchoolDBEntities())
{
var stud1 = (from s in context.Students.Include("Standard")
where s.StudentName == "Bill"
select s).FirstOrDefault<Student>();
}
Cú pháp phương thức LINQ:
using (var ctx = new SchoolDBEntities())
{
var stud1 = ctx.Students
.Include("Standard")
.Where(s => s.StudentName == "Bill")
.FirstOrDefault<Student>();
}
Các truy vấn LINQ ở trên sẽ tạo ra truy vấn SQL sau:
SELECT TOP (1)
[Extent1].[StudentID] AS [StudentID],
[Extent1].[StudentName] AS [StudentName],
[Extent2].[StandardId] AS [StandardId],
[Extent2].[StandardName] AS [StandardName],
[Extent2].[Description] AS [Description]
FROM [dbo].[Student] AS [Extent1]
LEFT OUTER JOIN [dbo].[Standard] AS [Extent2] ON [Extent1].[StandardId] = [Extent2].[StandardId]
WHERE 'Bill' = [Extent1].[StudentName]
Sử dụng biểu thức Lambda
Bạn cũng có thể sử dụng biểu thức lambda LINQ làm tham số trong phương thức Include
. Đối với điều này, hãy sử dụng namespace System.Data.Entity
và sử dụng biểu thức lambda như dưới đây:
using System;
using System.Data.Entity;
class Program
{
static void Main(string[] args)
{
using (var ctx = new SchoolDBEntities())
{
var stud1 = ctx.Students.Include(s => s.Standard)
.Where(s => s.StudentName == "Bill")
.FirstOrDefault<Student>();
}
}
}
Tải nhiều thực thể
Bạn cũng có thể Eager Loading nhiều cấp độ của các thực thể liên quan. Truy vấn sau sẽ tải các thực thể Student
, Standard
và Teacher
:
using (var ctx = new SchoolDBEntities())
{
var stud1 = ctx.Students.Include("Standard.Teachers")
.Where(s => s.StudentName == "Bill")
.FirstOrDefault<Student>();
}
Hoặc sử dụng biểu thức lambda như dưới đây:
using (var ctx = new SchoolDBEntities())
{
var stud1 = ctx.Students.Include(s => s.Standard.Teachers)
.Where(s => s.StudentName == "Bill")
.FirstOrDefault<Student>();
}
Truy vấn trên sẽ thực hiện truy vấn SQL sau trong cơ sở dữ liệu:
SELECT [Project2].[StudentID] AS [StudentID],
[Project2].[StudentName] AS [StudentName],
[Project2].[StandardId] AS [StandardId],
[Project2].[StandardName] AS [StandardName],
[Project2].[Description] AS [Description],
[Project2].[C1] AS [C1],
[Project2].[TeacherId] AS [TeacherId],
[Project2].[TeacherName] AS [TeacherName],
[Project2].[StandardId1] AS [StandardId1]
FROM ( SELECT
[Limit1].[StudentID] AS [StudentID],
[Limit1].[StudentName] AS [StudentName],
[Limit1].[StandardId1] AS [StandardId],
[Limit1].[StandardName] AS [StandardName],
[Limit1].[Description] AS [Description],
[Project1].[TeacherId] AS [TeacherId],
[Project1].[TeacherName] AS [TeacherName],
[Project1].[StandardId] AS [StandardId1],
CASE WHEN ([Project1].[TeacherId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
FROM (SELECT TOP (1) [Extent1].[StudentID] AS [StudentID], [Extent1].[StudentName] AS [StudentName], [Extent1].[StandardId] AS [StandardId2], [Extent2].[StandardId] AS [StandardId1], [Extent2].[StandardName] AS [StandardName], [Extent2].[Description] AS [Description]
FROM [dbo].[Student] AS [Extent1]
LEFT OUTER JOIN [dbo].[Standard] AS [Extent2] ON [Extent1].[StandardId] = [Extent2].[StandardId]
WHERE 'updated student' = [Extent1].[StudentName] ) AS [Limit1]
LEFT OUTER JOIN (SELECT
[Extent3].[TeacherId] AS [TeacherId],
[Extent3].[TeacherName] AS [TeacherName],
[Extent3].[StandardId] AS [StandardId]
FROM [dbo].[Teacher] AS [Extent3]
WHERE [Extent3].[StandardId] IS NOT NULL ) AS [Project1] ON [Limit1].[StandardId2] = [Project1].[StandardId]
) AS [Project2]
ORDER BY [Project2].[StudentID] ASC, [Project2].[StandardId] ASC, [Project2].[C1] ASC