刚开始接触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. Html与CSS学习书单

    1.Head First HTML与CSS(第二版) 豆瓣详情 这本书非常适合入门学习HTML与CSS它的内容不一定详实,但一定是你入门的首选.作为一本引进 图书翻译尚可.目前豆瓣评分9.3.

  2. 2T以上磁盘格式化

    1.安装软件 对于 Debian/Ubuntu 用户, 使用 APT-GET 命令或者 APT 命令来安装 parted #apt-get install -y parted 对于 RHEL/Cent ...

  3. maven 不能使用 snapshot 的解决方式

    最近项目需要用到snapshot的包来进行构建过程,但是怎么都下不了构建的snapshot包.查询了相关资料,发现网上的资料不全,特总结下: 我使用的是nexus来作为代理中央库proxy. 检查步骤 ...

  4. 第四次OO总结

    比较测试和正确性论证的效果 第13次作业是针对ALS电梯进行方法规格的测试,来判断方法运行的结果是否符合预期,是一种直观的验证错误的办法,但是不能确保程序完全正确,不过相比平时用的测试方法,这样效率更 ...

  5. appium 1.6.x版本去除安装Unlock、Setting

    (appium目录不知道可以查看appium运行日志) 修改目录/usr/local/lib/node_modules/appium/node_modules/appium-android-drive ...

  6. java上传文件获取跟目录的办法

    在java中获得文件的路径在我们做上传文件操作时是不可避免的.web 上运行1:this.getClass().getClassLoader().getResource("/"). ...

  7. How to enable C development in a Windows 10 development environment VM

    To enable C development in a Windows 10 development environment VM, follow these steps: Start VS in ...

  8. Cache高速缓冲存储器

    Cache的命中率:命中Cache的次数比总访问次数 平均访问时间:t(Cache)X命中次数+t(未命中)X未命中次数 Cache与主存的映射方式: 直接映射 全相联映射 组相联映射 图片来源:ht ...

  9. 初识Java Servlet

    Java Servlet是什么? Servlet的本质就是一个Java接口,之所以能生成动态的Web内容,是因为对客户的一个HTTP请求,Servlet通过接口这个规范重写了其中的方法,然后Web服务 ...

  10. Struts网站基于Filter的XSS漏洞修复

    下面的代码只支持struts2框架中的xss漏洞 第一步,创建过滤器XssFilter : package com.ulic.ulcif.filter; import java.io.IOExcept ...