从今天开始我们开始讲解EF中的实体状态和数据操作,这篇文章先讲解实体状态。

我们通过前面的学习,知道EF通过上下位负责跟踪实体的状态,实体状态的位置是在命名空间 System.Dat.Entity 里的 EntityState,具体状态有如下5种:

  1. Detached
  2. Unchanged
  3. Added
  4. Deleted
  5. Modified

下面我们分辨来讲解一下

零、Detached

有时候我们只需要实体显示,而不需要实体更新,为了提高性能,我们就就不需要EF上下文对实体进行跟踪,这个时候我们就用到了 Detached 状态。我们只需要在查询的时候使用 AsNoTracking() 来世的查询出来的对象是 Detached 状态。实例代码如下:

var person = db.Person.AsNoTracking().Where(p=>p.Id==1).FirstOrDefault();

注:因为 AsNoTracking 是DbQuery类的方法,因此要首先调用 AsNoTracking 方法。

一、Unchanged

在这个状态下实体被上下文追踪,但是数据库中的值没有发生任何改变。如果实体不存在于数据库,但是该实体要被上下文追踪,同时实体值未发生改变,这个时候就可以通过 Attach 进行附加追踪,然后将实体状态标记为 Unchanged 。 实例代码如下:

using (var db = new EFDbContext())
{
var user =new User()
{
Name = "张三",
Age = 12
}
db.User.Attach(user);
db.Entry(user).State = EntityState.Unchanged;
db.SaveChanges();
}

二、Added

当进行新增操作时就会用到 Added 状态。标记为 Added 状态时,表明尸体上下文被追踪但是不存在于数据库中,当我们调用 SaveChanges 方法时数据将保存进数据库。如果要将实体状态标记为该状态,可以使用两种方法:

  1. 间接标记,通过 Add 方法调用,示例代码如下:
using (var db = new EFDbContext())
{
var user = new User()
{
Name = "张三"
Age = 12
}
db.User.Add(user);
db.SaveChanges();
}
  1. 显式标记,通过调用 Entry 方法,示例代码如下:
using (var db = new EFDbContext())
{
var user = new User()
{
Name = "张三"
Age = 12
}
db.Entry(user).State = EntityState.Added;
db.SaveChanges();
}

三、Deleted

如果需要将实体从数据库中删除,可以使用 Deleted 状态,当调用 SaveChanges 方法时数据将会从数据库中删除。和 Added 状态一样,删除实体可以使用两种方法:

  1. 通过调用 Remove 或者是 RemoveRange 方法,示例代码如下:
using (var db = new EFDbContext())
{
var user = db.User..Where(p => p.Id == 1).FirstOrDefault();
db.User.Remove(user);
db.SaveChanges();
}

注: Remove 用于删除单个实体, RemoveRange 用于删除多个实体。

  1. 显式标记,通过调用 Entry 方法,示例代码如下:
using (var db = new EFDbContext())
{
var user = db.User..Where(p => p.Id == 1).FirstOrDefault();
db.Entry(user).State = EntityState.Deleted;
db.SaveChanges();
}

四、Modified

当我们修改数据时,需要用到 Modified 状态,当调用 SaveChanges 方法时数据将会修改数据库中的数据。在EF中修改数据,只有一种方法,通过调用 Entry 方法,示例代码如下:

using (var db = new EFDbContext())
{
var user = db.User..Where(p => p.Id == 1).FirstOrDefault();
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
}

五、特别提示

所有状态之间几乎都可以通过 Entry(T).State 的方式进行强制状态转换,因为状态改变都是依赖于 Id 的( Added 除外)。我们通过下图来了解一下上面五种状态的相互转换:

Entity Framework 实体状态的更多相关文章

  1. Entity Framework 实体框架的形成之旅--实体框架的开发的几个经验总结

    在前阵子,我对实体框架进行了一定的研究,然后把整个学习的过程开了一个系列,以逐步深入的方式解读实体框架的相关技术,期间每每碰到一些新的问题需要潜入研究.本文继续前面的主题介绍,着重从整体性的来总结一下 ...

  2. Entity FrameWork(实体框架)是以ADO.NET Entity FrameWork ,简称为EF

    Entity FrameWork(实体框架)是以ADO.NET Entity FrameWork ,简称为EF Entity FrameWork的特点 1.支持多种数据库(MSSQL.Oracle.M ...

  3. Entity Framework 实体框架的形成之旅--实体数据模型 (EDM)的处理(4)

    在前面几篇关于Entity Framework 实体框架的介绍里面,已经逐步对整个框架进行了一步步的演化,以期达到统一.高效.可重用性等目的,本文继续探讨基于泛型的仓储模式实体框架方面的改进优化,使我 ...

  4. Entity Framework 实体框架的形成之旅--为基础类库接口增加单元测试,对基类接口进行正确性校验(10)

    本篇介绍Entity Framework 实体框架的文章已经到了第十篇了,对实体框架的各个分层以及基类的封装管理,已经臻于完善,为了方便对基类接口的正确性校验,以及方便对以后完善或扩展接口进行回归测试 ...

  5. Entity Framework 实体框架的形成之旅--几种数据库操作的代码介绍(9)

    本篇主要对常规数据操作的处理和实体框架的处理代码进行对比,以便更容易学习理解实体框架里面,对各种数据库处理技巧,本篇介绍几种数据库操作的代码,包括写入中间表操作.联合中间表获取对象集合.递归操作.设置 ...

  6. Entity Framework 实体框架的形成之旅--界面操作的几个典型的处理(8)

    在上篇随笔<Entity Framework 实体框架的形成之旅--数据传输模型DTO和实体模型Entity的分离与联合>里面,介绍了在Entity Framework 实体框架里面引入了 ...

  7. Entity Framework 实体框架的形成之旅--数据传输模型DTO和实体模型Entity的分离与联合

    在使用Entity Framework 实体框架的时候,我们大多数时候操作的都是实体模型Entity,这个和数据库操作上下文结合,可以利用LINQ等各种方便手段,实现起来非常方便,一切看起来很美好.但 ...

  8. Entity Framework 实体框架的形成之旅--Code First模式中使用 Fluent API 配置(6)

    在前面的随笔<Entity Framework 实体框架的形成之旅--Code First的框架设计(5)>里介绍了基于Code First模式的实体框架的经验,这种方式自动处理出来的模式 ...

  9. Entity Framework 实体框架的形成之旅--Code First的框架设计(5)

    在前面几篇介绍了Entity Framework 实体框架的形成过程,整体框架主要是基于Database First的方式构建,也就是利用EDMX文件的映射关系,构建表与表之间的关系,这种模式弹性好, ...

随机推荐

  1. 2019年全网最热门的123个Java并发面试题总结

    前言 并发编程几乎是所有互联网公司面试必问的问题,并发编程是Java程序员最重要的技能之一,也是最难掌握的一种技能.它要求编程者对计算机最底层的运作原理有深刻的理解,同时要求编程者逻辑清晰.思维缜密, ...

  2. TieredMergePolicy

    setFloorSegmentMB多少MB一个层级,在此区间的segment分为一个floor. setMaxMergeAtOnce一次merge多少个segment. setSegmentsPerT ...

  3. Arrays.sort() VS Arrays.parallelSort()

    英文原文地址:Arrays.sort vs Arrays.parallelSort 作者:baeldung 翻译:高行行 1. 概述 我们都使用过 Arrays.sort() 对对象或原始数据类型数组 ...

  4. Oracle v_$和v$的解释

    以v_$mystat和v$mystat具体说明 grant语句中使用的v_$mystat和test用户访问的v$mystat不一样 这里说一下 v$mystat 和 v_$mystat 的区别 初始状 ...

  5. playbooks框架部署远程主机

    进入到ansible和python环境 进入python3.6虚拟环境 #su - deploy #source .py3-a2.5-env/bin/activate 加载ansible 2.5版本 ...

  6. Selenium的简单使用

    selenium的使用对于新手来说十分友好,因为他避开了如今网络中的异步加载抓取的困扰,使得我们大部分的时间可以用于提取信息和存储中,下面就简单的列一些使用的代码,希望给同样初学的你有一定的参考价值. ...

  7. .Net core路由高级用法

    先说startup中的路由 这里是我们现在用的默认路由,但是在使用当中也有麻烦.总而言之 用的不爽. 使用属性路由:RouteAttribute特性 默认的HomeController下面的Index ...

  8. 安装 Xen

    安装 Xen 安装支持 Xen 的相关工具: $ sudo apt-get install ubuntu-xen-server 下载和安装支持 Xen 的 Linux 内核: http://secur ...

  9. Linux环境下的network IO

    同步IO和异步IO,阻塞IO和非阻塞IO分别是什么,到底有什么区别?不同的人在不同的上下文下给出的答案是不同的.所以先限定一下本文的上下文. 本文讨论的背景是Linux环境下的network IO. ...

  10. Java小白入门:聊聊Java这门编程语言

    一.什么叫做编程 首先我们应该了解一下什么叫做编程. 百度百科词条的解释: 编程是编定程序的简称,是让计算机代我们解决某个问题,是对某个计算体系规定一定的运算方式,使计算体系按照该计算方式运行,并最终 ...