前言

  • 在编写代码的时候,我遇到了很多关于EntityFramework6的疑问,所以现在就提前把这些问题列出来做一下解答,以便在以后的代码编写过程中减少不必要的Bug。

EntityFramework6的延迟加载(Lazy Loading)是怎么一回事?

  • 首先EntityFramework6的延迟加载默认是被支持的,可以通过设置context.Configuration.LazyLoadingEnabled = false来禁止。
  • 当启用延迟加载的时候,EntityFramework访问实体的相关对象时,也就是一对一、一对多的属性时,EntityFramework会从你定义的实体派生出一个动态对象,然后覆盖你的子实体集合访问属性来实现。所以我们在定义POCO类的时候,会在关系属性前加上virtual 来修饰。如果不加修饰,就不会启动延迟加载。
  • 延迟加载,就是在查找某个实体时,会把相关联的实体对象或者集合全部加载出来。
  1. 启用延迟加载的情况,执行以下语句

  

  Sql Server Profiler监视情况如下:

  

  

  

  从上面的结果可以看出,当我们需要获取Role对象的时候,EntityFramework会把与之关联的对象以动态代理对象(DynamicProxy)

  的方式加载出来,数据库也向与之关联的表执行了多个关联查询才得到结果。

  2. 禁用延迟加载的情况,执行以下语句

  

  Sql Server Profiler监视情况如下:

  

  

  从上面的结果可以看出,执行的结果只有Role对象,与之关联的对象S_Menus为null,S_Users也没有结果,说明在禁用延迟加载的情况下,

  EntityFramework只对当前执行的上下文对象进行查询。Sql Server Profiler监视情况的结果也是如此,程序只执行了对S_Role表的读取

EntityFramework6DbContext 适合单例模式吗?

  • 之前我们在用三层架构的时候,我们通常会把DBHelper类的支持方法设置为静态方法,这样我们不需要实例化就可以调用执行方法。因此我在想DbContext我们能不能使用单例模式来进行创建?答案是不可以的。因为在同一个DbContext实例上下文中,如果A正在编辑某条数据,B也正在编辑某条数据,B在编辑后进行SaveChanges操作,就会把A编辑的数据也进行提交。而实际A编辑的数据可能被取消,但是也提交到了数据库进行更改,这肯定不是我们需要的结果。
  • 如果我们创建了多个DbContext的实例,就可能会遇到并发的问题,因为不同的实例可能会对同一条数据进行修改。EntityFramework可以使用乐观锁来解决此问题。

EntityFramework6怎样使用事务?

  • EntityFramework的DbContext中的SaveChanges就自带事务与分布式事务。
  • 如果我们的语句是在同一个DbContext的实例进行提交,那么DbContext中的SaveChanges就会默认启动事务,如果有一条语句执行失败,那么事务就会回滚。SaveChanges不会执行。
  • 如果我们的语句是在不同的DbContext的实例中进行提交,那我们就要采用分布式事务,也就是TransactionScope来开启。在TransactionScope中的任意一个DbContext的SaveChanges行失败后,其他的实例的SaveChanges也不会被执行,从而达到了事务控制的目的。

EntityFramework6中有缓存实现吗?

  • 就目前而言,EntityFramework的缓存只是维护其内部的DbContext,也就是常说的一级缓存。如果要对EntityFramework的查询结果对象进行缓存,我们就需要使用二级缓存来进行。常用的一些分布式应用缓存,如memcached或Redis都可以实现。CodePlex上也提供了一些二级缓存的实例,我们给以通过Nuget直接下载使用,比如下面的这俩个缓存组件:

    EntityFramework.Cache  https://efcache.codeplex.com/

IQueryable, IEnumerable, IList 傻傻分不清楚?

  

  以下结论引用园友Teddy Li的博客:

  • IQueryable和IEnumerable都是延时执行(Deferred Execution)的,而IList是即时执行(Eager Execution)
  • IQueryable和IEnumerable在每次执行时都必须连接数据库读取,而IList读取一次后,以后各次都不需连接数据库。前两者很容易造成重复读取,性能低下,并且可能引发数据不一致性
  • IQueryable和IEnumerable的区别:IEnumberalb使用的是LINQ to Object方式,它会将AsEnumerable()时对应的所有记录都先加载到内存,然后在此基础上再执行后来的Query。
  • 基于性能和数据一致性这两点,我们使用IQueryable时必须谨慎,而在大多数情况下我们应使用IList。当你打算马上使用查询后的结果(比如循环作逻辑处理或者填充到一个table/grid中),并且你不介意该查询会即时执行,使用ToList();当你希望查询后的结果可以供调用者(Consummer)作后续查询(比如这是一个"GetAll"的方法),或者你希望该查询延时执行,使用AsQueryable()

EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(五)的更多相关文章

  1. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(一)

    前言 本系列源自对EF6 CodeFirst的探索,但后来发现在自己项目中构建的时候遇到了一些问题以及一些解决方法,因此想作为一个系列写下来. 本系列并不是教你怎么做架构设计,但可以参照一下里面的方法 ...

  2. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(六)

    前言 在接下来的篇幅里将对系统的模块功能进行编写.主要以代码实现为主.这一篇我们需要完成系统模块“角色管理”的相关功能.完成后可以对系统框架结构有进一步了解. Abstract层 之前说过,Abstr ...

  3. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(完)

    前言 这一篇是本系列的最后一篇,虽然示例讲到这里就停止呢,但对于这些技术的学习远不能停止.虽然本示例讲的比较基础,但是正如我第一篇说到的,这个系列的目的不是说一些高端的架构设计,而是作为一个入门级,对 ...

  4. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(八)

    前言 本篇幅将对系统的菜单管理模块进行说明,系统的菜单采用树形结构,这样可以更好地方便层级设计和查看.本示例将说明如何通过EntityFramework读取递归的菜单树形结构,以及结合EasyUI的t ...

  5. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(七)

    前言 上一篇文章我们完成了系统角色管理的基本功能实现,也对系统层次结构进行了了解.这一篇我们将继续对系统的用户管理模块进行代码编写.代码没有做封装,所以大部分的逻辑代码都是相通的,只是在一些前端的细节 ...

  6. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(四)

    前言 这一篇,我们终于到了讲解Entity Framework CodeFirst 的时刻了,首先创建实体对象模型,然后会通过配置Fluent API的方式来对实体对象模型进行完整的数据库映射操作. ...

  7. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(三)

    前言 在上一篇中,我们依靠着EasyUI强大的前端布局特性把前端登录界面和主界面给搭建完成了.这一篇我们就要尝试着把整个解决方案部署到云端呢,也就是Visual Studio Online(TFVC) ...

  8. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(二)

    前言 写完第一篇后,我一直在想接下来应该从哪一方面开始讲.后来我觉得不用那么死板的把每一个课程和大纲都列出来吧,毕竟我又不是教书的,呵呵...我觉得就像做实验一样,我们一部分一部分的完成,最后总个结果 ...

  9. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(九)

    前言 这一篇我们将完成系统的权限设置功能以及不同角色用户登录系统后动态加载菜单.注意:此示例权限只针对菜单级,如果园友需要更复杂的系统权限设置,可以拓展到按钮级或属性级. 用户的登录采用Form认证来 ...

随机推荐

  1. LAMP环境搭建 (原创帖,转载请注明出处)

    =============================说在前面的话==========================第一安装Mysql第二安装Apache-httpd第三安装PHP 第四配置PH ...

  2. 高通camera学习笔记

    http://www.2cto.com/kf/201609/548725.html http://www.android100.org/html/201508/24/176303.html

  3. apache域名本地映射

    A: 第一步(搜索allow) 第二步(搜索vhost) 第三步(搜索rewrite) B: C:

  4. cocoapods使用一直Updating local specs repositories的解决方案

    pod install 换成pod install --verbose --no-repo-update这个命令,前面的命令被墙了 ,<pre id="best-content-226 ...

  5. /usr/include/features.h:367:25:fatal errorXXXXXX类似这种问题

    解决方案: sudo apt-get install g++=multilib //至于为什么还没搞清楚,搞清楚在写上来吧!

  6. Fragment碎片

    布局文件中添加碎片 1.在onCteate()方法中调用inflater.inflate()加载Fragment布局 2.在xml的<fragment>中需要显示指明碎片名称(androi ...

  7. JavaScript 中的对象

    JavaScript 中的对象 在 JavaScript 中,对象是数据(变量),拥有属性和方法. JavaScript 中的所有事物都是对象:字符串.数字.数组.日期,等等.   访问对象的属性 访 ...

  8. Javascript学习笔记:闭包题解(1)

    代码: function createFunctions(){ var result=[]; for(var i=0;i<10;i++){ result[i]=function(){ retur ...

  9. Linux进程管理

    一.进程管理简介 进程是正在执行的程序或命令,每一个进程都是一个运行实体,都有自己的地址空间,并占用一定的系统资源. 进程管理的作用: 1.判断服务器的健康状态 2.查看系统中的所有进程 3.杀死进程 ...

  10. em和rem

    em是一个相对值,是相对于父元素的值. body{ font-size:62.5%;/*10/16*100%=62.5%*/ } h1{ font-size:2.4em;/*2.4em*10=24px ...