刚开始接触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. Windows 自动化补丁管理

    Windows 自动化补丁管理 Desktop Central,这一倍受欢迎的补丁管理软件旨在修补可能导致安全薄弱.破坏关键系统数据或导致系统不可用的漏洞.管理此类软件漏洞对网络管理员来说简直是噩梦. ...

  2. PHP日期格式化函数

    date函数 描述:格式化一个本地时间/日期 语法:string date(string format [,int timestamp]) format字符 说明 format字符 说明 Y 4位数字 ...

  3. CoUninitialize引发的一个错误

    程序开始已使用CoUninitialize,后边的函数又再次调用CoUninitialize,判断返回值,导致函数提前退出返回异常.

  4. php日志报错child exited with code 0 after seconds from start

    因为日志文件老是有这种提示: [27-May-2015 15:13:48] NOTICE: [pool www] child 3998 started [27-May-2015 15:13:59] N ...

  5. JavaScript基础视频教程总结(061-070章)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  6. CDR锁定方式

    每个通道的PMA包括一个通道PLL可以配置成接收器CDR.还可以把通道1和4的PLL配置成CMU PLL用于发送器. CDR有两种锁定方式 1.Lock-to-Reference Mode(LTR) ...

  7. 数据库导出sql

    mysqldump -u 用户名 -p 数据库名 > 导出的文件名 mysqldump -u wcnc -p smgp_apps_wcnc > wcnc.sql

  8. 【原创】岁月如歌 一款网易歌单生成pdf的软件

    介绍 这是一款可以将网易云音乐的歌单中所有歌词输出为pdf的软件. 项目持续维护地址 http://brightguo.com/song-list-to-pdf/ 目前没有搜到相关网易歌单导出为pdf ...

  9. linux 解决乱码问题

    乱码分两种情况: 1.终端(纯 shell 界面)的乱码  vi /etc/profile export LC_ALL="zh_CN.GB18030:zh_CN.GB2312:zh_CN.G ...

  10. C语言setjmp用法解析

    https://www.cnblogs.com/hbiner/p/3261437.html