刚开始接触EF框架的时候总是不明白:

  为什么查询出来的对象 Remove()、再 SaveChanges()就会把数据删除。而自己 new 一个Person()对象,然后 Remove()不行?

  为什么查询出来的对象修改属性值后、再 SaveChanges()就会把数据库中的数据修改?

随着慢慢的深入研究和网上查找资料就明白了,原来EF的背后还有一套自己的对象状态管理体系

在EF中的对象有五个状态

  1、Detach(游离态,脱离态)

    --> 自己动手new出来的对象就是处于Detach状态的

  2、Unchange(未改变)

    --> 当你使用EF框架进行查询的时候,查询出来的对象都是处于这个状态

  3、Added(新增)

    --> 一个自己new出来的对象想要加入数据库中,必须首先要转换到这个状态

  4、Deleted(删除)

    --> 要对从EF框架中查询出来的对象进行删除操作的话,要首先转换到此状态下

  5、Modified(被修改)

    --> 对从EF框架中查询出来的对象进行改动后,对象会处于此状态下

他们之间转换的关系与途径大致可以用下面这幅图来描述:

从图中可以看出,一共有两个入口:

1、直接new 

2、使用EF进行查询

只有使用这两种方法拿到了对象以后才能进行图中一系列的转换操作。

当然,在实际的应用中我们也可以强制改变对象的状态,不经过执行Add()、Delete()等函数操作。

这是因为,当 SavaChanged()方法执行期间,会查看当前对象的 EntityState 的值,决定是去新增(Added)、修改(Modified)、删除(Deleted)或者什么也不做(UnChanged)

使用方法如下:

var p = new Person();
p.Id = ; ctx.Entry(p).State = System.Data.Entity.EntityState.Unchanged;

(更新、删除等都是根据Id 进行的)

目前所知道的几个关于EF优化的方法:

  1) 如果查询出来的对象只是供显示使用,不会修改、删除后保存,那么可以使用AsNoTracking()来使得查询出来的对象是 Detached 状态,这样对对象的修改也还是 Detached状态,EF 不再跟踪这个对象状态的改变,能够提升性能,因为在管理对象状态的过程中也是需要消耗的。

  2) 如果要批量删除某表中的数据,如果查询出来一个个 Remove() 的话,性能就太坑爹了,在考虑性能的前提下可以使用原生的SQL语句来执行批量删除操作,用法如下:

      ctx.Database.ExecuteSqlCommand("update T_DeputyUserPerms set IsDeleted=true where DeputyUserId={0}", DeputyUserId);

        --> 注:使用ef框架执行的sql都采用参数化执行sql语句的方式,防止sql注入式漏洞,更安全。(通过查看生成的sql语句可以直观地发现)

EntityFramework中对象的状态管理(笔记)的更多相关文章

  1. React项目中使用Mobx状态管理(二)

    并上一节使用的是普通的数据状态管理,不过官方推荐使用装饰器模式,而在默认的react项目中是不支持装饰器的,需要手动启用. 官方参考 一.添加配置 官方提供了四种方法, 方法一.使用TypeScrip ...

  2. React项目中使用Mobx状态管理(一)

    1.安装 $ yarn add mobx mobx-react 2.新建store/index.js,存放数据(以下思路仅限于父子组件的简单应用) 注意:这里暂时没使用装饰器@observable,装 ...

  3. 关于hibernate中对象的三种状态分析

    一,首先hibernate中对象的状态有三种:瞬态.游离态和持久态,三种状态转化的方法都是通过session来调用,瞬态到持久态的方法有save().saveOrUpdate().get().load ...

  4. Hibernate框架--对象的状态,缓存, 映射

    回顾Hibernate第二天: 1.  一对多与多对一 2. 多对多 3. inverse/cascade 4. 关联关系的维护 一对多: <set name="映射的集合属性&quo ...

  5. HttpClient-03Http状态管理

    最初,Http被设计成一个无状态的,面向请求/响应的协议,所以它不能在逻辑相关的http请求/响应中保持状态会话.由于越来越多的系统使用http协议,其中包括http从来没有想支持的系统,比如电子商务 ...

  6. java之hibernate之session中对象的生命周期

    1. session是用来执行对象的crud操作,并且session是对象事务工厂.session是线程级别的,所以生命周期比较短. 2.session中对象的生命周期图: 3.session中对象的 ...

  7. vue状态管理vuex从浅入深详细讲解

    1.vuex简介以及创建一个简单的仓库 vuex是专门为vue框架而设计出的一个公共数据管理框架,任何组件都可以通过状态管理仓库数据沟通,也可以统一从仓库获取数据,在比较大型的应用中,数据交互庞大的情 ...

  8. Spark Streaming状态管理函数updateStateByKey和mapWithState

    Spark Streaming状态管理函数updateStateByKey和mapWithState 一.状态管理函数 二.mapWithState 2.1关于mapWithState 2.2mapW ...

  9. HttpClient4.3教程 第三章 Http状态管理

    最初,Http被设计成一个无状态的,面向请求/响应的协议,所以它不能在逻辑相关的http请求/响应中保持状态会话.由于越来越多的系统使用http协议,其中包括http从来没有想支持的系统,比如电子商务 ...

随机推荐

  1. <c:forEach>循环列表,获取勾选的checkbox中某个<td>的值

    <table> <!--列表表头 开始 --> <tr> <th><input type="checkbox" name=&q ...

  2. SSM+MyBatis框架详解

  3. [swarthmore cs75] Lab 0 Warmup & Basic OCaml

    课程回顾 Swarthmore学院16年开的编译系统课,总共10次大作业.本随笔记录了相关的课堂笔记以及第1次大作业. 什么是编译 编译就是执行Program->Program'转换的过程,如下 ...

  4. 将表格添加到Word文档中 ,包括表格样式设置

    创建 Table 对象并设置其属性 在您将表格插入文档之前,必须创建 Table 对象并设置其属性. 要设置表格的属性,请创建TableProperties对象并为其提供值. TablePropert ...

  5. Linux-3.0.8中基于S5PV210的GPIO模块代码追踪和分析

    编写按键驱动时,想知道内核是如何管理GPIO的,所以开始追踪代码,中间走了一些弯路,现记录于此. 追踪代码之前,我猜测:第一,这部分代码应该在系统set up阶段执行:第二,GPIO的代码应该在mac ...

  6. jsp获取当前项目跟路径

    在jsp中获取当前项目的根路径: <% String basePath = request.getScheme() + "://"+ request.getServerNam ...

  7. gii配置

    下载完成后不要设置urlManager http://zjm.testyii.com/index.php?r=gii 即可进入gii页面 或者是 将'urlManager'=> [ 'enabl ...

  8. SSD硬盘安装win10 且安装千牛工作台频繁卡死问题解决过程

    之前win7的时候突然出现卡死现象,具体表现为:磁盘占用百分之百,千牛窗口无法关闭,点截图按钮后,千牛关闭了,并没有截图,千牛聊天输入/无法出现快捷短语了,电脑桌面点击右键没反应,任务栏点击右键也没反 ...

  9. apache与tomcat负载集群集成方法配置

    apache与tomcat负载集群集成方法有3种jk.jk_proxy.http_proxy apache:httpd-2.2.17-win32-x86-no_ssl.msi tomcat:apach ...

  10. 目标检测算法(1)目标检测中的问题描述和R-CNN算法

    目标检测(object detection)是计算机视觉中非常具有挑战性的一项工作,一方面它是其他很多后续视觉任务的基础,另一方面目标检测不仅需要预测区域,还要进行分类,因此问题更加复杂.最近的5年使 ...