zoukankan      html  css  js  c++  java
  • EF中延迟加载的那些事

    延迟加载又称懒加载,通俗一点就是关联了一个对象,不用的时候不去查这个对象,当调用的时候再组织sql去查出这个对象的相关内容。

    一.在使用EF时,我们会发现借助于框架生成的实体类中的的导航属性通常是标记 virtual的,这是为何呢?

     二.让我们通过几个例子来发现其中的奥秘

    下面的代码是通用的查询,先是打印了查询生成的sql,接着查询出一个Employee对象并带出对应的Dempartment对象。

           using (DemoEntities db = new DemoEntities())
                {
                    db.Database.Log = sql => Console.WriteLine(sql);
                    Employee emp = db.Employees.FirstOrDefault();
                    Console.WriteLine(emp.Name);
                    Console.WriteLine(emp.Department.Name);    
                }

       1.导航属性上有virtual的情况下查询两条sql,一条是查出Employee另一条是查Dempartment

     2.现在我们将默认的导航属性中的virtual去掉会发生什么呢,让我们带着疑惑继续往下看

    三.原理探究

    看到这是不是感觉很怪异喽,加上virtual就能正常执行,去掉就不行了么。这是啥原理呢

    1.我们把代码修改一下

         using (DemoEntities db = new DemoEntities())
                {
                    Employee emp = db.Employees.FirstOrDefault();
                    Console.WriteLine(emp.GetType());  //打印emp的类型
                    Console.WriteLine(emp.GetType().BaseType);  //打印emp类型对应的父类
                    Console.WriteLine(emp.Name);
                    Console.WriteLine(emp.Department.Name);
                }

    在原有的基础上我们打印了一下对应对象的类型

    2.我们还是先看看默认有virtual的情况

     通过执行代码我们发现,我们所声明的Employee的对象的类型竟然不是Employee而是一个名字特别长的另一个对象,而这个对象的父类才是Employee

    3.我们将导航属性的virtual去掉再执行代码看看有什么变化

     看到这里的差异,我们似乎发现了点什么。先说说virtual关键字吧,virtual是虚方法,通常是用于子类的重写。那么这里我们不难推测当导航属性有virtual关键字时,EF帮我们生成了一个

    父类是Employee名字老长老长的那个类,在这个类的实现中,重写了一下,当Department为空时,它会去数据库里查一下这个Department对象,所以加上virtual关键字时就会对应两条sql

    类似效果如下所示

        class Employee_515EB7DF3C6168BFE9566BD863543E3AED9398AFF473BAB129D9B32823D6E8A3 : Employee {
                private Department _department;
                public override Department Department
                {
                    get
                    {
                        if (_department==null)
                        {
                            //去数据库中查询Department的信息
                        }
                        return _department;
                    }
                }
            }
  • 相关阅读:
    爸爸妈妈儿子女儿吃水果问题以及五个哲学家吃饭问题
    同步与互斥中的购票和退票问题的PV操作与实现
    创建react&ts&antd项目
    在POM配置Maven plugin提示错误“Plugin execution not covered by lifecycle configuration”的解决方案
    aws rds 储存空间占用 异常排查 存储空间占满
    Linux下clang、gcc、intel编译器最新版本安装笔记
    extern "C"与extern "C" { … }的差别
    gcc预处理指令之#pragma once
    指向类的成员变量的指针
    Java程序中使用SQLite总结
  • 原文地址:https://www.cnblogs.com/HTLucky/p/13335031.html
Copyright © 2011-2022 走看看