EF--EntityState相互转换
- EF对数据做什么样的操作,是根据EF的上下文实体状态决定,实体状态有以下5种状态,下面我们就分别看下这5种状态
数据准备,我们看到学生表里有20000名学生记录,最后1位学生的学生编号为0000020000
1、Detached--实体跟上下文压根没关系
我们看到我新创建了名学生,学号为0000020001,他是第20001位学生,此时打印上下文实体状态,实体和上下文是分离状态,没有任何关系,Detached是表示连内存跟踪都没有建立,跟上下文dbContext没有任何关系
Student newStudent = new Student()
{
Student_ID = "",
Student_Name = "猪猪打屁股",
Student_Sex = "男",
Student_Identity_Card = "",
Student_Birthday = DateTime.Now,
Student_Email = "menglin2010@126.com",
Student_Class = "741903613@qq.com",
Create_Time = DateTime.Now
};
//1、Detached--实体跟context压根没关系
{
using (SchoolDBEntities dbContext = new SchoolDBEntities())
{
Console.WriteLine(dbContext.Entry<Student>(newStudent).State);//实体跟context没关系 Detached
newStudent.Student_Name = "小鱼儿";
Console.WriteLine(dbContext.Entry<Student>(newStudent).State);//Detached
dbContext.SaveChanges();//Detached啥事儿不发生
}
}
2、Added--添加
我们看到刚开始,newStudent这个学生和上下文是Detached分离状态,当把newStudent添加到上下文的Students集合里后,再打印newStudent的状态,newStudent就是Added状态了,当执行dbContext.SaveChange()后,把这个学生添加到表里,最后打印newStudent的状态,发现是Unchanged状态,Unchanged的意思是上下文和newStudent建立了跟踪,但是newStudent没有发生改变
//2、Added--添加
{
using (SchoolDBEntities dbContext = new SchoolDBEntities())
{
Console.WriteLine(dbContext.Entry<Student>(newStudent).State);//Detached
dbContext.Students.Add(newStudent);//插入数据(自增主键在插入成功后,会自动赋值过去)
Console.WriteLine(dbContext.Entry<Student>(newStudent).State);//Added
dbContext.SaveChanges();
Console.WriteLine(dbContext.Entry<Student>(newStudent).State);//Unchanged(跟踪,但是没变化)
}
}
3、Unchanged--跟踪,但是没变化
Unchanged就是上下文和实体建立了跟踪,但是实体的值没有发生改变
4、Modified--内存Clone
把上次添加的那个“猪猪打屁股”的学生查出来,打印实体状态是Unchanged表示上下文建立了跟踪,但是实体未改变,然后修改学生姓名为“猪大头”,再打印实体状态是Modified,表示实体已发生了修改,当执行dbContext.SaveChange()后,把对这个学生的修改保存到表里,最后再打印newStudent的状态,发现是Unchanged状态,表示上下文和实体建立了跟踪,但是实体的值没有发生改变
{
using (SchoolDBEntities dbContext = new SchoolDBEntities())
{
Student currentStudent = dbContext.Students.Find("");//即时查询
Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);//Unchanged(跟踪,但是没变化)
currentStudent.Student_Name = "猪大头";//修改--内存clone
Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);//Modified
dbContext.SaveChanges();//更新数据库,因为状态是Modified
Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);//Unchanged(跟踪,但是没变化)
}
}
5、Deleted--删除
把上次修改的那个“猪大头”的学生查出来,打印其实体状态是Unchanged表示上下文建立了跟踪,但是实体未改变,然后从上下文的Students集合中移除,再打印实体状态是Deleted,表示实体已删除,当执行dbContext.SaveChange()后,把这个学生从表里删除掉,最后再打印newStudent的状态,发现是Detached状态,表示上下文和实体已经分离,和上下文没有任何关系了
{
using (SchoolDBEntities dbContext = new SchoolDBEntities())
{
Student currentStudent = dbContext.Students.Find("");//即时查询
Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);//Unchanged(跟踪,但是没变化)
dbContext.Students.Remove(currentStudent);
Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);//Deleted
dbContext.SaveChanges();//删除数据,因为状态是Deleted
Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);//Detached已经从内存移除了
}
}
- 实体和上下文建立跟踪的两种方式
1、主动查询方式
我们看到通过主键学号为“0000020000”查询出的这个学生实体和上下文建立了跟踪,只不过学生实体值没有发生任何改变,所以实体的状态是Unchanged
{
using (SchoolDBEntities dbContext = new SchoolDBEntities())
{
//1、查询方式
Student currentStudent = dbContext.Students.Find("");
Console.WriteLine(dbContext.Entry<Student>(currentStudent).State);
}
}
2、Attach附加方式
修改前学号为0000020000的这名学生叫“石兴江”,性别为“女”,new Student()1个学生只不过这个学生的学号是在Student表里存在的“0000020000”,打印oldStudent实体状态是Detached,跟dbContext压根没关系,然后把oldStudent附加到上下文中,再打印oldStudent实体状态是Unchanged(这里说明下:oldStudent的Student_Identity_Card,Student_Birthday,Student_Email等属性是null,难道oldStudent实体状态不应该是Modified吗?难道不是把Student_Identity_Card,Student_Birthday,Student_Email改为null值吗?这里状态还是Unchanged,说明了属性值为null在EF里不是改为null,而是不做更改,最后一张图证明了这点Student_Identity_Card,Student_Birthday,Student_Email等属性在表里没有被改为null值),然后修改学号为0000020000的这名学生名称为“石兴江_Att”,性别为“男”,再打印oldStudent实体状态是Modified(因为实体发生了变化),dbContext.SaveChanges();执行后,我们发现0000020000的这名学生名字被改为了“石兴江_Att”,性别被改为了“男”,而Student_Identity_Card,Student_Birthday,Student_Email等字段值并没有被改为null
{
using (SchoolDBEntities dbContext = new SchoolDBEntities())
{
Student oldStudent = new Student()
{
Student_ID = ""
}; Console.WriteLine(dbContext.Entry<Student>(oldStudent).State);//Detached--实体跟dbContext压根没关系
dbContext.Students.Attach(oldStudent);
Console.WriteLine(dbContext.Entry<Student>(oldStudent).State);//Unchanged(跟踪,但是没变化)
oldStudent.Student_Name = "石兴江_Att";
oldStudent.Student_Sex = "男";
Console.WriteLine(dbContext.Entry<Student>(oldStudent).State);//Modified(因为实体发生了变化)
dbContext.SaveChanges();
}
}
- 按需更新,只更新指定的字段
修改前,学号为“0000000001”的学生名字叫“赵峰真”,身份证号码为"1234567890",我们先查询出学号为“0000000001”的这名学生,打印实体状态为Unchanged,表示实体建立了跟踪但是实体未改变,然后修改学生姓名为“赵峰真001”,修改学生身份证号码为“abc”,再打印实体状态为Modified(因为实体发生了变化),然后指定这个学生的Student_Name属性为已修改,指定Student_Identity_Card属性为未被更改过(实际上我们本身是改了Student_Identity_Card的值为abc),最后dbContext.SaveChanges();后,我们发现只有学生姓名变成了“赵峰真001” ,而学生身份号码并没有被更改为abc“”
//按需更新--只修改指定的字段
{
using (SchoolDBEntities dbContext = new SchoolDBEntities())
{
Student student = dbContext.Students.Find("");//即时查询
Console.WriteLine(dbContext.Entry<Student>(student).State);
student.Student_Name = "赵峰真001";
student.Student_Identity_Card = "abc";
Console.WriteLine(dbContext.Entry<Student>(student).State);
dbContext.Entry<Student>(student).Property("Student_Name").IsModified = true;//指定字段被改过
dbContext.Entry<Student>(student).Property("Student_Identity_Card").IsModified = false;//指定字段未被改过
Console.WriteLine(dbContext.Entry<Student>(student).State);
dbContext.SaveChanges();
}
}
EF--EntityState相互转换的更多相关文章
- %E3%80%90%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B%E3%80%91
"%3Cdiv%20class%3D%22htmledit_views%22%20id%3D%22content_views%22%3E%0A%20%20%20%20%20%20%20%20 ...
- 使用EF自带的EntityState枚举和自定义枚举实现单个和多个实体的增删改查
本文目录 使用EntityState枚举实现单个实体的增/删/改 增加:DbSet.Add = > EntityState.Added 标记实体为未改变:EntityState.Unchange ...
- 关于mvc5+EF里面的db.Entry(model).State = EntityState.Modified报错问题
最近在使用mvc5+EF的的时候用到了这句话 db.Entry(model).State = EntityState.Modified 看上去很简单的修改数据,但是一直报错,说是key已经存在,不能修 ...
- EF中的EntityState几个状态的说明
之前使用EF,我们都是通过调用SaveChanges方法把增加/修改/删除的数据提交到数据库,但是上下文是如何知道实体对象是增加.修改还是删除呢?答案是通过EntityState枚举来判断的,我们看一 ...
- 关于EF框架EntityState的几种状态
在使用EF框架时,我们通常都是通过调用SaveChanges方法把增加/修改/删除的数据提交到数据库,但是上下文是如何知道实体对象是增加.修改还是删除呢?答案是通过EntityState的枚举值来判断 ...
- 【EF学习笔记09】----------使用 EntityState 枚举标记实体状态,实现增删改查
讲解之前,先来看一下我们的数据库结构:班级表 学生表 如上图,实体状态由EntityState枚举定义:Detached(未跟踪).Unchanged(未改变).Added(已添加).Deleted( ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(5)-EF增删改查
系列目录 前言 为了符合后面更新后的重构系统,文章于2016-11-1日重写 回顾上一节的解决方案,我们看出了解决方案中类库的关系 这里要说明一点MVC!=三层 他们大约是这样的一种关系 代码实现 上 ...
- 1.【使用EF Code-First方式和Fluent API来探讨EF中的关系】
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/relationship-in-entity-framework-using-code-firs ...
- 2.EF中 Code-First 方式的数据库迁移
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/code-first-migrations-with-entity-framework/ 系列目 ...
- 3.EF 6.0 Code-First实现增删查改
原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-entity-framework-5-0-code- ...
随机推荐
- Java基础系列2:深入理解String类
Java基础系列2:深入理解String类 String是Java中最为常用的数据类型之一,也是面试中比较常被问到的基础知识点,本篇就聊聊Java中的String.主要包括如下的五个内容: Strin ...
- Docker获取镜像报错docker: Error response from daemon
docker: Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled ...
- SpringBoot分布式篇Ⅷ --- 整合SpringCloud
SpringCloud是一个分布式的整体解决方案.Spring Cloud为开发者提供了在分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一次性token,全局锁,leader选举.分布 ...
- 读《Clean Code 代码整洁之道》之感悟
盲目自信,自认为已经敲了几年代码,还看什么整洁之道啊.我那可爱的书架读懂了我的心思,很明事理的保护起来这本小可爱,未曾让它与我牵手 最近项目中的 bug 有点多,改动代码十分吃力,每看一行代码都带一句 ...
- Shrio | java.io.IOException: Resource [classpath:shiro.ini] could not be found
案例 今天项目启动时一直报异常,看了错误日志发现是shrio文件找不到引起的,异常: java.io.IOException: Resource [classpath:shiro.ini] could ...
- ubuntu-14.04.6配置IP
配置环境与要求: 网卡列表如下: eth0:DHCP模式 eth1:静态模式 网络概况与要求: 192.168.2.0/24为外网(获取网络资源) 10.5.1.0/24为内网(终端服务管理) 系统默 ...
- Sea.js 手册与文档
Sea.js 手册与文档 首页 | 索引 目录 何为 CommonJS 何为 CommonJS 模块 为何封装模块 何为 CommonJS? CommonJS 是一个有志于构建 JavaScript ...
- 3、IP地址划分
划分子网方法:1.你所选择的子网掩码将会产生多少个子网?:2 的x 次方(x 代表被借走的主机位数)2.每个子网能有多少主机?: 2 的y 次方-2(y 代表被借走之后剩余的主机位数)3.块大小:bl ...
- 基于H5与webGL的 3d 电子围栏展示
前言 现代工业化的推进在极大加速现代化进程的同时也带来的相应的安全隐患,在传统的可视化监控领域,一般都是基于 Web SCADA 的前端技术来实现 2D 可视化监控,本系统采用 Hightopo 的 ...
- eclipse导入项目时的一些准备
导入前的工作: 1.因为别人项目的运行环境可能和我们不一样,所以首先要在要导入的项目里面找到.setting文件,修改下面的xml文件,这个文件里面是关于服务器的一些配置的信息,你可以改成与你电脑一样 ...