EntityFramework - 加载方式
引用自: http://www.cnblogs.com/nianming/p/3494781.html
EF 关联实体加载方式有三种
Lazy Loading
Eager Loading
Explicit Loading
其中: Lazy Loading 是自动延迟加载 Explicit Loading是手动延迟加载
Lazy Loading
在用到具体数据的时候才会加载进内存
当使用 ToList() 或者直接使用 List<> 接受数据时不会引发懒加载
必要的条件是:
1. POCO类必须是 public 且不能为 sealed
2. 导航属性标记为 virtual (懒加载的机制是 生成新的子类覆盖原来的POCO类)
3. Configuation.LazyLoadingEnabled 为 true
假设一个类 User 包含外键 Class
当对这个类集使用 ToList() 将会加载所有 User 到内存, 但不会加载 任何 Class
只有具体引用到某个 User 的 Class 时, 才引发加载.
并且,
根据每次循环都会查询一次数据库
如果不需要这样的设定,
则可以直接使用 User.Include("Class")的方式, 连同 Class 一起加载进内存
POCO类
public class Province { public int Id { get; set; } public string Name { get; set; } public virtual Governor Governor { get; set; } public virtual IList<City> Cities { get; set; } } public class Governor { public int Id { get; set; } public string Name { get; set; } } public class City { public int Id { get; set; } public string Name { get; set; } }
测试代码
private static void LazyLoading(DEMODBContext ctx) { //发送一条查询到数据库,查询所有的province var list = ctx.Province.ToList(); foreach (var province in list) { //每次遍历(用到导航属性时)都发送2条查询,一条查询当前province包含的city和另一条查询当前province的governor //如果ctx.Configuration.LazyLoadingEnabled为false或者前者为true,但是导航属性没有标注为virtual,下面的操作都会抛出异常 Print(province); } } private static void EagerLoading(DEMODBContext ctx) { var list = ctx.Province.Include("Cities").Include("Governor"); //发送一条查询到数据库库,查询所有的province并关联city和governor //var list = ctx.Province.Include(t => t.Cities).Include(t => t.Governor); foreach (var province in list) { //不管ctx.Configuration.LazyLoadingEnabled为false,还是没有标注导航属性virtual,都不会抛出异常 Print(province); } } private static void ExplicitLoading(DEMODBContext ctx) { //发送一条查询到数据库,查询所有的province var list = ctx.Province.ToList(); foreach (var province in list) { var p = ctx.Entry(province); //发送一条查询,查询所有当前province的city p.Collection(t => t.Cities).Load(); //发送一条查询,查询当前province的governor p.Reference(t => t.Governor).Load(); //不管ctx.Configuration.LazyLoadingEnabled为false,还是没有标注导航属性virtual,都不会抛出异常 Print(province); } } private static void Print(Province province) { Console.WriteLine("省:【{0}】,市:【{1}】,省长:【{2}】", province.Name, string.Join(",", province.Cities.Select(t => t.Name)), province.Governor.Name); }