EF加载数据的方式:
- 预加载 eager loading
- 延迟加载 lazy loading
- 显示加载 explicit loading
预先加载会加载所有相关的实体,通过Include方法来实现
1 using (var context = new BloggingContext()) 2 { 3 // Load all blogs and related posts 4 var blogs1 = context.Blogs 5 .Include(b => b.Posts) 6 .ToList(); 7 8 // Load one blogs and its related posts 9 var blog1 = context.Blogs 10 .Where(b => b.Name == "ADO.NET Blog") 11 .Include(b => b.Posts) 12 .FirstOrDefault(); 13 14 // Load all blogs and related posts 15 // using a string to specify the relationship 16 var blogs2 = context.Blogs 17 .Include("Posts") 18 .ToList(); 19 20 // Load one blog and its related posts 21 // using a string to specify the relationship 22 var blog2 = context.Blogs 23 .Where(b => b.Name == "ADO.NET Blog") 24 .Include("Posts") 25 .FirstOrDefault(); 26 }
预先加载也支持多层级加载相关的实体
1 using (var context = new BloggingContext()) 2 { 3 // Load all blogs, all related posts, and all related comments 4 var blogs1 = context.Blogs 5 .Include(b => b.Posts.Select(p => p.Comments)) 6 .ToList(); 7 8 // Load all users their related profiles, and related avatar 9 var users1 = context.Users 10 .Include(u => u.Profile.Avatar) 11 .ToList(); 12 13 // Load all blogs, all related posts, and all related comments 14 // using a string to specify the relationships 15 var blogs2 = context.Blogs 16 .Include("Posts.Comments") 17 .ToList(); 18 19 // Load all users their related profiles, and related avatar 20 // using a string to specify the relationships 21 var users2 = context.Users 22 .Include("Profile.Avatar") 23 .ToList(); 24 }
延迟加载只有相关的属性被访问时才去加载,延迟加载的的实现是在导航属性前加上virtual
1 public class Blog 2 { 3 public int BlogId { get; set; } 4 public string Name { get; set; } 5 public string Url { get; set; } 6 public string Tags { get; set; } 7 8 public virtual ICollection<Post> Posts { get; set; } 9 }
对于包含导航属性的实体,如果要序列化最好关闭延迟加载
对于所有的实体都关闭延迟加载可以在context中设置
1 public class BloggingContext : DbContext 2 { 3 public BloggingContext() 4 { 5 this.Configuration.LazyLoadingEnabled = false; 6 } 7 }
尽管延迟加载被禁用,仍然可以使用系显示加载去加载相关的实体
1 using (var context = new BloggingContext()) 2 { 3 var post = context.Posts.Find(2); 4 5 // Load the blog related to a given post 6 context.Entry(post).Reference(p => p.Blog).Load(); 7 8 // Load the blog related to a given post using a string 9 context.Entry(post).Reference("Blog").Load(); 10 11 var blog = context.Blogs.Find(1); 12 13 // Load the posts related to a given blog 14 context.Entry(blog).Collection(p => p.Posts).Load(); 15 16 // Load the posts related to a given blog 17 // using a string to specify the relationship 18 context.Entry(blog).Collection("Posts").Load(); 19 } 20 //Reference放法在导航属性对应一个单独的实体时使用 21 //Collection 方法在导航属性对应一个实体集合时使用
当显示加载相关实体时可以使用filters
1 using (var context = new BloggingContext()) 2 { 3 var blog = context.Blogs.Find(1); 4 5 // Load the posts with the 'entity-framework' tag related to a given blog 6 context.Entry(blog) 7 .Collection(b => b.Posts) 8 .Query() 9 .Where(p => p.Tags.Contains("entity-framework") 10 .Load(); 11 12 // Load the posts with the 'entity-framework' tag related to a given blog 13 // using a string to specify the relationship 14 context.Entry(blog) 15 .Collection("Posts") 16 .Query() 17 .Where(p => p.Tags.Contains("entity-framework") 18 .Load(); 19 } 20 21 using (var context = new BloggingContext()) 22 { 23 var blog = context.Blogs.Find(1); 24 25 // Count how many posts the blog has 26 var postCount = context.Entry(blog) 27 .Collection(b => b.Posts) 28 .Query() 29 .Count(); 30 }