• 提升Entityframework效率的几种方法


    1、了解EF的三种数据加载模式

      a)Lazy Loading

        i.默认ef是使用此模式,显示开启在DbContext的构造器中使用Configuration.LazyLoadingEnabled=true;

        ii.此模式中(codefirst),领域模型不能被声明为sealed,导航属性必须声明为virtual。因为框架会自动为模型生成一个代理类,在访问导航属性时代理类重写导航属性,从数据源读取数据并返回实体或集合。

        iii.在对应到遍历实体的时候再遍历对应导航属性,此时需要开启sqlserver的mars选项,可直接在连接字串中配置。

        iv.Lazy Loading模式只有在访问对应实体的导航属性时才会加载该数据。

      b)Eager Loading

        i.开启ef的Eager Loading模式需要在DbContext的构造其中使用Configuration.LazyLoadingEnabled=false;或者(codefirst)将领域模型声明为sealed,导航属性声明为非virtual,这样都可以导致Lazy Loading的失效。

        ii.在Eager Loading模式下,加载导航属性的值需要显示调用Include方法,传入导航属性属性名的字符串。或者引入System.Data.Entity命名空间,使用Include的强类型方法。

        iii.Eager Loading模式将主数据和导航属性数据一次性全部加载进内存。

      c)Explicit Loading

        i.Explicit Loading和Lazy Loading相似。导航属性的数据都是在主数据加载完后加载的,不同的是Lazy Loading会在访问导航属性时自动加载数据而Explicit Loading需要在访问导航属性数据前手动调用DbContext.Entry(T).Collection(x=>x.NavigationProperty).Load();[访问实体集合]或DbContext.Entry(T).Reference(x=>x.NavigationProperty).Load();[访问实体]此时数据被加载到内存中,然后访问导航属性即可。以上Load()方法返回的是void类型。如果将Load()替换为Query(),Query()方法返回的是IQueryAble<T>类型,所以可直接在返回结果上进行读取或遍历操作。

        ii.Explicit Loading模式下允许领域模型的导航属性声明为非virtual,但是导航属性声明为virtual且未置LazyLoadingEnabled为false会自动启用Lazy Loading模式。

        iii.Explicit Loading模式需要手动控制在什么时候加载数据。

    2、在已知实体标识的情况下使用Find方法查找,该方法会先在EF的对象管理缓存查找,如果没有再在数据源中查找。这在某些情况下比直接调用Single或First等高效。若查不到数据,该方法返回null。

    3、在更改导航属性上的对象时,先将对象加载到EF的上下文中,EF可以知道该对象的状态是新添加的还是修改或已删除的,然后再应用到实体的导航属性上。比如直接在实体导航属性上添加一个对象和先将新建对象放入EF的上下文中再关联到实体的导航属性上,EF在SaveChanges时就不需要插叙数据库来判断这个新加的对象是否已存在,以减少生成的sql语句。

    4、在以下操作中会触发DetectChanges方法的调用。

      a)         DbSet.Add        DbSet.Find        DbSet.Remove                   DbSet.Local      DbContext.SaveChanges

      b)         任何对DbSet执行的Linq查询

      c)         DbSet.Attach            DbContext.GetValidationErrors                DbContext.Entry      DbChangeTracker.Entries

    触发DetectChanges方法在性能要求苛刻的环境下是需要避免的,通过将DbContext.Configuration.AutoDetectChangesEnabled置为false可以阻止EF自动调用DetectChanges方法。如果我们进行了一系列的API调用却不改变任何对象,可以避免一些不必要的执行DetectChanges的过程。例如再大量数据插入的时候。

    5、在获取数据时,如果只将数据作为展示,而不需要进行状态跟踪修改,使用AsNoTracking()方法将会有明显的性能提升。使用AsNoTracking()方法需要引入System.Data.Entity命名空间。

  • 相关阅读:
    pycharm运行程序,总是出现IPthony界面(IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help. PyDev console: using IPython 6.2.1)
    《剑指offer》第十一题:旋转数组的最小数字
    《剑指offer》第十题:斐波那契数列
    《剑指offer》第九题:用两个栈实现队列
    《剑指offer》第八题:二叉树的下一个节点
    《剑指offer》第七题:重建二叉树
    《剑指offer》第六题:从尾到头打印链表
    《剑指offer》第五题:替换空格
    《剑指offer》第四题:二维数组中的查找
    《剑指offer》第三题II:不修改数组找出重复的数字
  • 原文地址:https://www.cnblogs.com/xdlysk/p/3126786.html
Copyright © 2020-2023  润新知