EF 6 DB-First系列--Entity Framework中的查询--延迟加载

延迟加载

延迟加载是延迟相关数据的加载,直到您特别请求它。它与立即加载相反。例如,Student实体包含StudentAddress实体。在延迟加载中,上下文首先从数据库加载Student实体数据,然后当我们访问StudentAddress属性时,它将加载StudentAddress实体,如下所示。

实体类:

    public class Student
    {
        public int StudentID { get; set; }
        public string StudentName { get; set; }
        public Nullable<int> StandardId { get; set; }
        public byte[] RowVersion { get; set; }
    
        public virtual Standard Standard { get; set; } 

        public virtual StudentAddress StudentAddress { get; set; } //在EntityFramework中被标记为virtual的导航属性的数据在查询的时候默认是不会被查询的,只有当使用到该属性的时候才会去数据库查询,默认是延迟加载的
        
        public virtual ICollection<Course> Courses { get; set; }
}
public class Standard
{
    public int StandardId { get; set; }
    public string StandardName { get; set; }
    public string Description { get; set; }
    
    public virtual ICollection<Student> Students { get; set; }
        
    public virtual ICollection<Teacher> Teachers { get; set; }
}
using (var ctx = new SchoolDBEntities())
{
    //只加载Student数据
    IList<Student> studList = ctx.Students.ToList<Student>();

    Student std = studList[0];

    //当使用到Student中的StudentAddress属性时才会去数据库查询StudentAddress的数据(单独的SQL查询)
	StudentAddress add = std.StudentAddress;

}

上面显示的代码将导致两个SQL查询。首先,它将获取所有的学生:

SELECT 
[Extent1].[StudentID] AS [StudentID], 
[Extent1].[StudentName] AS [StudentName], 
[Extent1].[StandardId] AS [StandardId]FROM [dbo].[Student] AS [Extent1]

然后,当我们需要用到StudentAddress的数据时,它会发送以下查询:

exec sp_executesql N'SELECT 
[Extent1].[StudentID] AS [StudentID], 
[Extent1].[Address1] AS [Address1], 
[Extent1].[Address2] AS [Address2], 
[Extent1].[City] AS [City], 
[Extent1].[State] AS [State]
FROM [dbo].[StudentAddress] AS [Extent1]
WHERE [Extent1].[StudentID] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=1

禁用延迟加载

我们可以禁用特定实体或上下文的延迟加载。若要关闭特定属性的延迟加载,请不要将其设置为virtual。要关闭上下文中所有实体的延迟加载,请将其configuration属性设置为false。

关闭某个实体中的导航属性延迟加载:

public class Student
{
        public int StudentID { get; set; }
        public string StudentName { get; set; }
        public Nullable<int> StandardId { get; set; }
        public byte[] RowVersion { get; set; }
 
        public StudentAddress StudentAddress { get; set; } //在EntityFramework中没有标记为virtual的导航属性的数据在查询的时候会自动进行关联加载
        
        public virtual ICollection<Course> Courses { get; set; }
}

全局禁用延迟加载(不建议影响性能):

using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Core.Objects;
using System.Linq;
    
public partial class SchoolDBEntities : DbContext
{
    public SchoolDBEntities(): base("name=SchoolDBEntities")
    {
        this.Configuration.LazyLoadingEnabled = false;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
    }
}

延迟加载规则:
1、context.Configuration.ProxyCreationEnabled应该为true。

2、context.Configuration.LazyLoadingEnabled应该是true。

3、导航属性应该定义为public, virtual。如果属性未定义为virtual, Context将不会进行延迟加载,而是默认立即加载。

参考

https://www.entityframeworktutorial.net/
https://msdn.microsoft.com/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值