一、预先加载
1、简单的来说就是查询某实体类型时,一并加载相关实体;读取实体时会检索其相关数据,当实体类中有多个相关实体时,可以同时指定需要加载的数据(一个或者多个都可以,也可以多层级,根据需要指定),通过Include和ThenInclude方法进行指定
举例说明:1>单个预先加载
var blogs = context.Blogs .Include(blog => blog.Posts) .ToList();
2>多个预先加载
var blogs = context.Blogs .Include(blog => blog.Posts).Include(blog => blog.Owner).ToList();
3>层级预先加载
var blogs = context.Blogs .Include(blog => blog.Posts) .ThenInclude(post => post.Author) .ThenInclude(author => author.Photo) .ToList();
var blogs = context.Blogs .Include(blog => blog.Posts) .ThenInclude(post => post.Author) .ThenInclude(author => author.Photo) .Include(blog => blog.Owner) .ThenInclude(owner => owner.Photo) .ToList();
二、显示加载
1、首次读取实体时,不检索相关数据,必须编写代码才能在需要检索时检索相关数据,使用Load方法进行显示加载
1>Entry() :获取实体对象的代理类
2> DbContext.Entry(...)API 显式加载导航属性 举例说明
var blog = context.Blogs .Single(b => b.BlogId == 1);
context.Entry(blog) .Collection(b => b.Posts) .Load();
context.Entry(blog) .Reference(b => b.Owner) .Load();
3>导航属性的LINQ查询,即在预先加载出导航属性后可可以直接进行LINQ查询,举例说明
var blog = context.Blogs .Single(b => b.BlogId == 1);
var postCount = context.Entry(blog) .Collection(b => b.Posts) .Query() .Count();
4>删选要加载到内存中的关联实体;ToList()会加载到内存中,举例说明
var blog = context.Blogs .Single(b => b.BlogId == 1);
var goodPosts = context.Entry(blog) .Collection(b => b.Posts) .Query() .Where(p => p.Rating > 3) .ToList();
三、延迟加载
1>延迟加载又称按需加载,即需要加载时,提交sql语句与数据库进行交互,降低交互的损耗,提高性能
2>导航属性启用延迟加载满足的条件:必须是 virtual 且 类为可被继承的类,即非sealed类
举例说明简单的应用:
首先安装Microsoft.EntityFrameworkCore.Proxies包,接下来有两种方式启用延迟加载的包
<1>在上下文类中使用
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString);
<2>在添加上下文服务时使用
.AddDbContext<BloggingContext>(
b => b.UseLazyLoadingProxies()
.UseSqlServer(myConnectionString));
复杂情况使用参照微软官方文档:https://docs.microsoft.com/zh-cn/ef/core/querying/related-data#explicit-loading
来源:https://www.cnblogs.com/heyangming/p/12023204.html