📅  最后修改于: 2020-11-21 07:28:48             🧑  作者: Mango
延迟加载是这样的过程:首次访问引用一个或多个实体的属性时,将从数据库自动加载一个实体或一组实体。延迟加载意味着延迟相关数据的加载,直到您明确要求为止。
使用POCO实体类型时,通过创建派生代理类型的实例,然后重写虚拟属性以添加加载钩子,可以实现延迟加载。
延迟加载几乎是默认设置。
如果您保留默认配置,并且没有在查询中明确告诉Entity Framework您需要除延迟加载以外的其他功能,那么延迟加载就是您将获得的。
例如,当使用Student实体类时,相关的注册将在首次访问“注册”导航属性时加载。
导航属性应定义为public,virtual。如果该属性未定义为虚拟,则上下文不会进行延迟加载。
以下是一个Student类,其中包含Enrollments的导航属性。
public partial class Student {
public Student() {
this.Enrollments = new HashSet();
}
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public System.DateTime EnrollmentDate { get; set; }
public virtual ICollection Enrollments { get; set; }
}
让我们看一个简单的示例,在该示例中,首先从数据库中加载学生名单,然后在需要时加载特定学生的入学申请。
class Program {
static void Main(string[] args) {
using (var context = new UniContextEntities()) {
//Loading students only
IList students = context.Students.ToList();
foreach (var student in students) {
string name = student.FirstMidName + " " + student.LastName;
Console.WriteLine("ID: {0}, Name: {1}", student.ID, name);
foreach (var enrollment in student.Enrollments) {
Console.WriteLine("Enrollment ID: {0}, Course ID: {1}",
enrollment.EnrollmentID, enrollment.CourseID);
}
}
Console.ReadKey();
}
}
}
编译并执行上述代码后,您将收到以下输出。
ID: 1, Name: Ali Alexander
Enrollment ID: 1, Course ID: 1050
Enrollment ID: 2, Course ID: 4022
Enrollment ID: 3, Course ID: 4041
ID: 2, Name: Meredith Alonso
Enrollment ID: 4, Course ID: 1045
Enrollment ID: 5, Course ID: 3141
Enrollment ID: 6, Course ID: 2021
ID: 3, Name: Arturo Anand
Enrollment ID: 7, Course ID: 1050
ID: 4, Name: Gytis Barzdukas
Enrollment ID: 8, Course ID: 1050
Enrollment ID: 9, Course ID: 4022
ID: 5, Name: Yan Li
Enrollment ID: 10, Course ID: 4041
ID: 6, Name: Peggy Justice
Enrollment ID: 11, Course ID: 1045
ID: 7, Name: Laura Norman
Enrollment ID: 12, Course ID: 3141
延迟加载和序列化不能很好地结合在一起,如果您不小心,可能会因为启用了延迟加载而最终查询整个数据库。在序列化实体之前,最好先关闭延迟加载,这是一个好习惯。
可以通过使Enrollments属性为非虚拟来关闭Enrollments集合的延迟加载,如以下示例所示。
public partial class Student {
public Student() {
this.Enrollments = new HashSet();
}
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
public System.DateTime EnrollmentDate { get; set; }
public ICollection Enrollments { get; set; }
}
通过将Configuration属性上的标志设置为false,可以关闭上下文中所有实体的延迟加载,如以下示例所示。
public partial class UniContextEntities : DbContext {
public UniContextEntities(): base("name = UniContextEntities") {
this.Configuration.LazyLoadingEnabled = false;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
throw new UnintentionalCodeFirstException();
}
}
关闭延迟加载后,现在当您再次运行以上示例时,您将看到未加载注册并且仅检索学生数据。
ID: 1, Name: Ali Alexander
ID: 2, Name: Meredith Alons
ID: 3, Name: Arturo Anand
ID: 4, Name: Gytis Barzduka
ID: 5, Name: Yan Li
ID: 6, Name: Peggy Justice
ID: 7, Name: Laura Norman
ID: 8, Name: Nino Olivetto
我们建议您逐步执行上述示例,以更好地理解。