刚开始接触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. 第九周助教工作总结——NWNU李泓毅

    1.助教博客链接: https://www.cnblogs.com/NWNU-LHY/ 2.作业要求博客链接: https://www.cnblogs.com/nwnu-daizh/p/1072688 ...

  2. flex弹性盒子布局

    一.在需要使用弹性盒子的容器上添加属性:display:flex 或者 display:inline-flex; 二.在父容器上添加flex-direction设置子元素主轴方向: 不写默认值是X轴从 ...

  3. 怎么解决syntaxerror:non-utf-8 code starting with \xc4'in file

    怎么解决syntaxerror:non-utf-8 code starting with \xc4'in file   首行增加,已测试可用. # coding=gbk   程序中出现中文,运行的时候 ...

  4. html、css基础整理

    1.块元素与行内元素之间的转换: HTML可以将元素分类方式分为行内元素.块状元素和行内块状元素三种.这三者是可以互相转换的,使用display属性能够将三者任意转换: (1)display:inli ...

  5. PopupWindow计算弹出位置

    1.首先自定义PopupWindow    popWindowView= LinearLayout.inflate(context, R.layout.popupWindow,null);    po ...

  6. JS canvas标签动态绘制图型

    使用canvas标签动态绘制图型,当点击鼠标时,以鼠标点击的坐标作为图形中心点.当点击数为偶数时画三角形,当点击数为奇数时画五角星 <!DOCTYPE HTML> <html> ...

  7. DB2日常维护常用命令

    1.检查是否有僵尸进程 ps -emo THREAD | grep -i Z | grep -i 实例名 2.处理死锁  --第一步:查看所有死锁  db2 get snapshot for lock ...

  8. Android学习笔记(1):常用按钮点击事件处理方式

    1.从布局文件获取对应的控件然后对其添加点击监听器. Button loginBtn; @Override protected void onCreate(Bundle savedInstanceSt ...

  9. Openvswitch手册(5): VLAN and Bonding

    我们这一节来看Port 一般来说一个Port就是一个Interface,当然也有一个Port对应多个Interface的情况,成为Bond VLAN Configuration Port的一个重要的方 ...

  10. Android屏幕相关的概念

    1. 屏幕尺寸 实际的物理尺寸,作为屏幕的对角线测量. 为简单起见,安卓所有的实际屏幕尺寸为四个广义的大小:小,正常,大,和特大. 2. 屏幕密度 一个屏幕的物理区域内像素的数量:通常称为DPI(每英 ...