EF中的三种加载方式
EF性能优化
一、Lazy Loading
【延迟加载】或者【懒加载】: 对于这种类型的加载,在您访问导航属性时,会从数据源自动加载相关实体。 使用此加载类型时,请注意,如果实体尚未在 ObjectContext 中,则您访问的每个导航属性都会导致针对数据源执行一个单独的查询。
- 开启或者关闭懒加载
context.Configuration.ProxyCreationEnabled =true;//开启
context.Configuration.LazyLoadingEnabled = false;//关闭
在下面的代码中,首先会执行一次查询,并将返回的结果存放在变量customers 中。而foreach循环会在每一次循环过程中独立进行一次查询,所以,如果数据库表Customer中有100条记录,那么整个过程将产生101次查询。
using (var dbcontext= new ModelFirstDemoEntities())
{
#region 延迟加载:用的时候加载
var customers = from c in dbcontext.Customer
select c;
foreach (var cus in customers)
{
Console.WriteLine(cus.Id);
foreach (var order in cus.Order) //根据导航属性,自动查询客户的订单
{
Console.WriteLine(order.OrderContent);
}
}
#endregion
}
二、Eager Loading
【贪婪加载】或【及时加载】或【预加载】: 当您了解应用程序需要的相关实体的图形的确切形状时,可以使用 ObjectQuery 的 Include 方法来定义查询路径,此查询路径控制将哪些相关实体作为初始查询的一部分返回。 当定义查询路径时,仅需对数据库请求一次,即可在单个结果集中返回查询路径所定义的所有实体,并且属于在路径中定义的类型的所有相关实体将随查询返回的每个对象一起加载。
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ToList();
}
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.Include(blog => blog.Posts)
.ThenInclude(post => post.Author)
.ToList();
}
如果你查看SQl Server Profiler中的跟踪信息,你会发现只有一次数据交互过程,即程序只通过一次查询便获取到了所有需要的数据。它也可以减少程序与数据库的交互次数。不过仍然有缺点,那就是如果数据量较大,一次性将所有数据载入内存往往并不是最明智的选择。.Include(Entity)方法允许级联使用,你可以预先加载具有多层级结构的数据。
三、Explicit Loading
【显示加载】:将实体显式加载到 ObjectContext 需要多次往返数据库,并且可能需要多个活动结果集,但是返回的数据量仅限于所加载的实体。 可以对 EntityCollection或 EntityReference 使用 Load 方法或对 ObjectContext 使用 LoadProperty 方法,以便从数据源显式检索相关实体。 对于 Load 方法的每个调用都会打开与数据库的连接,以检索相关信息。 这可确保在没有对相关实体的显式请求时,始终不会执行查询。
- Reference()方法获取导航属性信息,Load()精确加载
- Collection()集合导航属性
using (var context = new BloggingContext())
{
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();
}
设计模式:https://blog.csdn.net/sinat_40003796/article/details/125595458