原文:Loading Related Entities
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 }
View Code
预先加载也支持多层级加载相关的实体
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 }
View Code
延迟加载只有相关的属性被访问时才去加载,延迟加载的的实现是在导航属性前加上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 }
View Code
对于包含导航属性的实体,如果要序列化最好关闭延迟加载
对于所有的实体都关闭延迟加载可以在context中设置
1 public class BloggingContext : DbContext
2 {
3 public BloggingContext()
4 {
5 this.Configuration.LazyLoadingEnabled = false;
6 }
7 }
View Code
尽管延迟加载被禁用,仍然可以使用系显示加载去加载相关的实体
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 方法在导航属性对应一个实体集合时使用
View Code
当显示加载相关实体时可以使用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 }
View Code