• 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相互转换的更多相关文章

  1. %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 ...

  2. 使用EF自带的EntityState枚举和自定义枚举实现单个和多个实体的增删改查

    本文目录 使用EntityState枚举实现单个实体的增/删/改 增加:DbSet.Add = > EntityState.Added 标记实体为未改变:EntityState.Unchange ...

  3. 关于mvc5+EF里面的db.Entry(model).State = EntityState.Modified报错问题

    最近在使用mvc5+EF的的时候用到了这句话 db.Entry(model).State = EntityState.Modified 看上去很简单的修改数据,但是一直报错,说是key已经存在,不能修 ...

  4. EF中的EntityState几个状态的说明

    之前使用EF,我们都是通过调用SaveChanges方法把增加/修改/删除的数据提交到数据库,但是上下文是如何知道实体对象是增加.修改还是删除呢?答案是通过EntityState枚举来判断的,我们看一 ...

  5. 关于EF框架EntityState的几种状态

    在使用EF框架时,我们通常都是通过调用SaveChanges方法把增加/修改/删除的数据提交到数据库,但是上下文是如何知道实体对象是增加.修改还是删除呢?答案是通过EntityState的枚举值来判断 ...

  6. 【EF学习笔记09】----------使用 EntityState 枚举标记实体状态,实现增删改查

    讲解之前,先来看一下我们的数据库结构:班级表 学生表 如上图,实体状态由EntityState枚举定义:Detached(未跟踪).Unchanged(未改变).Added(已添加).Deleted( ...

  7. ASP.NET MVC5+EF6+EasyUI 后台管理系统(5)-EF增删改查

    系列目录 前言 为了符合后面更新后的重构系统,文章于2016-11-1日重写 回顾上一节的解决方案,我们看出了解决方案中类库的关系 这里要说明一点MVC!=三层 他们大约是这样的一种关系 代码实现 上 ...

  8. 1.【使用EF Code-First方式和Fluent API来探讨EF中的关系】

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/relationship-in-entity-framework-using-code-firs ...

  9. 2.EF中 Code-First 方式的数据库迁移

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/code-first-migrations-with-entity-framework/ 系列目 ...

  10. 3.EF 6.0 Code-First实现增删查改

    原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-entity-framework-5-0-code- ...

随机推荐

  1. 解决Android studio遇见Could not find common.jar (android.arch.core:common:1.0.0).错误

    不知道怎么回事就发生的错误,翻墙找到的解决方法,如下: Error:Could not find common.jar (android.arch.core:common:1.0.0).Searche ...

  2. CountDownLatch CyclicBarrier和 Semaphore

    CountDownLatch CyclicBarrier和 Semaphore 原理 基于AQS实现. 让需要的暂时阻塞的线程,进入一个死循环里面,得到某个条件后再退出循环,以此实现阻塞当前线程的效果 ...

  3. Git详解之Git起步

    前言 本章介绍开始使用 Git 前的相关知识.我们会先了解一些版本控制工具的历史背景,然后试着让 Git 在你的系统上跑起来,直到最后配置好,可以正常开始开发工作.读完本章,你就会明白为什么 Git ...

  4. hadoop-2.10.0安装hive-2.3.6

    公司建立数仓,hive是必不可少的,hive是建立在hadoop基础上的数据库,前面已经搭建起了hadoop高可用,要学习hive,先从搭建开始,下面梳理一下hive搭建过程 1.下载hive安装包 ...

  5. python学习Day06--编码

    [主要内容] 1. is 和 == 区别 id()函数 == 判断两边的值 is 判断内存地址回顾编码: 1. ASCII: 英文, 特殊字符, 数字, 8bit, 1byte 2. GBK: 中文 ...

  6. LESS 用法入门

    本文旨在加深对 LESS 的理解和记忆,供自己开发时参考.相信对没有接触过 LESS 的程序员还是有用的,大佬绕路. 一. 安装和使用 LESS 1.1 安装 使用命令行安装 LESS npm ins ...

  7. tensorflow MNIST Convolutional Neural Network

    tensorflow MNIST Convolutional Neural Network MNIST CNN 包含的几个部分: Weight Initialization Convolution a ...

  8. Codeforces_835

    A.比较两人总时间. #include<bits/stdc++.h> using namespace std; int s,v1,v2,t1,t2; int main() { ios::s ...

  9. 设计模式——Adapter Pattern 适配器模式

    我第一次接触设计模式,选取了四大类型里面的结构型,这类型的特点是关注类&对象之间的组合(使用继承),我从中选取适配器模式来具体学习. 一.适配器模式(Adapter Pattern)定义: 适 ...

  10. Shiro权限验证说明

    1.简介 shiro是一个安全框架,是Apache的一个子项目.shiro提供了:认证.授权.加密.会话管理.与web集成.缓存等模块. 1.1.模块介绍 Authentication:用户身份识别, ...