刚开始接触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. mysql时间戳转换

    数据表中time是时间戳格式,转化成正常的时间格式 SELECT id,TIME,FROM_UNIXTIME(TIME,'%Y-%m-%d %H:%m:%S'),incline_id FROM inc ...

  2. 数据结构C语言顺序表

    #include <stdio.h> #include <stdlib.h> typedef int EmenType; typedef struct Node { int d ...

  3. 2019浙大校赛--J--Extended Twin Composite Number(毒瘤水题)

    毒瘤出题人,坑了我们好久,从基本的素数筛选,到埃氏筛法,到随机数快速素数判定,到费马小定理,好好的水题做成了数论题. 结果答案是 2*n=n+3*n,特判1,2. 以下为毒瘤题目: 题目大意: 输入一 ...

  4. prim算法和克鲁斯卡尔算法

    Prim 设图G=(V,E)是一个具有n个顶点的连通网,其生成树的顶点集合为U.首先把v0放入U,再在所有的u∈U,v∈V-U的边(u,v)∈E中找一条最小权值的边,加入生成树,并把该边的v加入U集合 ...

  5. IDEL中easyui使用jstl和el出现传值不显示的问题

    <%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding=& ...

  6. parrot os 安装后更改更新源

    parrot os 安装后 parrot os 自带的更新源更新速度太慢(需要几个小时) 提供如下更新源 中国 USTC(中国科学技术大学和USTCLUG) - 合肥大学 CMCC 1 Gbps Ce ...

  7. Java中不定项参数(可变参数)的作用和使用方式

    引言: 我们在编写方法的过程中,可能会遇见一个方法有不确定参数个数的情况.一般我们会用方法重载来解决问题: //方法重载,解决参数个数不确定问题 public void method(); publi ...

  8. 一次java Cpu占用过高的排查

    某一个项目CPU占用率一直很高,经常在40%-50%之间,最近比较闲,就开始了排查工作. 1.通过 jstack命令输出进程的堆栈信息 jstack 2788 >C:\log.txt 将堆栈信息 ...

  9. Akka-CQRS(6)- read-side

    前面我们全面介绍了在akka-cluster环境下实现的CQRS写端write-side.简单来说就是把发生事件描述作为对象严格按发生时间顺序写入数据库.这些事件对象一般是按照二进制binary方式如 ...

  10. Eclipse 常用快捷键使用说明

    注释快捷键 Ctrl + / 选中代码后快速加//注释, 再次用取消//注释 Ctrl + Shift + / 选中代码后快速加/* */注释 Ctrl + Shift + \ 选中代码后快速取消/* ...