• 第五节: EF高级属性(一) 之 本地缓存、立即加载、延迟加载(不含导航属性)


    一. 本地缓存

       从这个章节开始,介绍一下EF的一些高级特性,这里介绍的首先介绍的EF的本地缓存,在前面的“EF增删改”章节中介绍过该特性(SaveChanges一次性会作用于本地缓存中所有的状态的变化),在这里介绍一下本地缓存的另外一个用途。

      ① Find方法通过主键查询数据,主键相同的查询,只有第一次访问数据库,其它均从缓存中读取。

      ② 延迟加载的数据,在第一次使用的使用时访问数据库,后面无论再使用多少次,均是从内存中读取了。

    1             Console.WriteLine("--------------------------- 1.本地缓存属性   ------------------------------------");
    2                 db.Database.Log += c => Console.WriteLine(c);
    3                 //以下4个根据主键id查询,查询了一次,都存到本地缓存里了,所以user2不查询数据库,但user3的id不同,所以查询数据库
    4                 var user1 = db.Set<TestInfor>().Find("2");
    5                 var user2 = db.Set<TestInfor>().Find("2");
    6                 var user3 = db.Set<TestInfor>().Find("3");

    二. 立即加载

      这里的立即加载指单表,不含主外键的情况。

      所谓的立即加载就是代码执行的时候直接去数据库查询,与是否立即使用无关,查出来后放到本地缓存里,以后再次使用的时候,从本地缓存中读取。

      常见的立即加载的的标记:toList() 、FirstOrDefault() 。

    1         Console.WriteLine("--------------------------- 2.即时加载   ------------------------------------");
    2 
    3                 ////以下3个属于立即查询,所以每次都要查询数据库,不缓存
    4                 var user5 = db.Set<TestInfor>().Where(u => u.id == "2").FirstOrDefault();
    5                 var user6 = db.Set<TestInfor>().Where(u => u.id == "2").FirstOrDefault();
    6                 var user7 = db.Set<TestInfor>().Where(u => u.id == "2").FirstOrDefault();

    三. 延迟加载

    这里的延迟加载指单表,不含主外键的情况。

    1. 定义:只有我们需要数据的时候,才去数据库查询

      比如:我们需要根据条件判断,通过Where来拼接条件(IQueryable),在拼接的过程中,并没有访问数据库,只有在最终使用的时候,才访问数据库。

      特别注意:调用的时候要foreach循环来调用,只有第一次使用的时候去访问数据库,其它的都是从本地缓存中读取。

    2. 禁用延迟加载的方法:

    a:如果结果是集合,在拼接的结尾加 toList() ,其它类型调用其它方法

    b:如果结果是单个实体,在拼接的结尾加 FirstOrDefault()

    3. 好处:保证了数据的实时性,什么时候用,什么时候查询

    4. 弊端:每用一次,就需要查询一次数据,服务器压力大

    5. 延迟加载的实际开发场景:

    分页要要经历where多个条件查询、skip、take、toList,如果每调用一个方法都连接一个数据库,那么在拼接过程中就访问了3次数据库,而且可能数据量非常多,所以这个时候使用延迟加载,只有在所有sql语句拼接完的最后一步才连接数据库。

    总结:只要查询结果实现了IQueryable接口类的,那么查询结果都是延迟加载的。

     1           Console.WriteLine("--------------------------- 3.延迟加载   ------------------------------------");
     2                 IQueryable<TestInfor> user4 = db.Set<TestInfor>().Where(u => u.id != "123");
     3                 IQueryable<TestInfor> user6 = db.Set<TestInfor>().Where(u => u.id != "123");
     4                 foreach (var item in user4)
     5                 {
     6                     Console.WriteLine("我要从数据库中读取数据了:" + item.txt1);
     7                 }
     8                 foreach (var item in user4)
     9                 {
    10                     Console.WriteLine("我要从数据库中读取数据了2:" + item.txt1);
    11                 }
    12                 foreach (var item in user6)
    13                 {
    14                     Console.WriteLine("我要从数据库中读取数据了3:" + item.txt1);
    15                 }

    延迟加载上述案例分析:

    * IQueryable类型的 user4和user6, 都是延迟加载的,下面foreach第一次使用该对象的时候去数据库查询。

    * 这里会有这么几个问题:

    * ①:foreach第一次遍历的时候去数据库中查询user4,然后放到本地缓存里,后面无论循环多少次,都是从本地缓存中读取user4。

    * ②:前两个foreach操控的对象都是user4,所以第二个foreach无论哪次循环,都是从本地缓存中读取

    * ③:第三个foreach操控的对象是user6,同样是在foreach第一次循环的时候去数据库查询,所以在代码执行到第一个或第二个foreach的时候,

    * 手动去数据库改数据,当执行到第三个foreach,查询出来的数据就是修改后的了。

  • 相关阅读:
    在SQL2000怎樣用動態實現SQL2005的nvarchar(max)功能
    行列互换
    c#+GUI在aspx页面画图
    做网站用UTF8还是GB2312?
    Mvc如何做权限
    表白网
    vs2008保存很慢,提速
    MVC 向View传值
    aspx画图表
    什么是MVC
  • 原文地址:https://www.cnblogs.com/yaopengfei/p/7701481.html
Copyright © 2020-2023  润新知