Entity Framework 4 in Action读书笔记——第六章:理解实体的生命周期(一)
本章内容包括:
|
我们先从分析实体的生命周期和它的状态开始。
实体生命周期
在其生存期期间,一个实体只有一个状态。在了解如何检索状态之前,先看看什么是实体状态。实体状态就是声明为以下值的System.Data.EntityState类型的枚举:
Added——实体标记为added。
Deleted——实体标记为deleted。
Modified——实体已经被修改。
Unchanged——实体还没有被修改。
Detached——实体不能被追踪。
这些状态代表什么?状态与什么相关?实体如何从一个状态传递到另一个状态?这些状态影响数据库吗?回答这些问题,必须先看看对象生命周期背后的概念。
理解实体状态
如第三章所述,上下文(context)持有对从数据库检索的所有对象的引用。对我们的讨论更重要的是,上下文保持实体的状态并且维护对实体属性的修改。这一功能称为change tracking(或object tracking)。
如果在上下文外部创建一个实体,它的状态为Detached,因为上下文不能追踪它。
如果将一个实体附加到上下文,它的状态就变为Unchanged。如果从数据库中检索一个实体,然后从上下文中移除,实体的状态为Detached。如果检索一个实体,释放上下文,然后创建一个新的上下文,给它添加一个实体,这个实体的状态则为Added。这些例子说明,状态是实体和对它持有引用的上下文间的关系。
让我们看个例子。假设在OrderIT中有两个方法,第一个是检索关于customer的数据,第二个用于更新数据。客户使用第一个方法检索数据并在窗体中显示。在这个方法中,创建了一个上下文来检索数据,然后销毁上下文。
用户修改了一些数据,例如发货地址(shipping address),然后调用第二个方法更新修改的customer数据并保存它。在网络服务(web service)方法中,创建一个新的上下文并且将实体附加到它。新的上下文并不知道什么数据已经被修改了,除非它去数据库中比较。
去数据库中的代价比较大,所以并不会自动执行。这就是说实体附加到上下文时,它进入Unchanged状态,因为上下文对修改一无所知。如果实体状态反映数据库的实际状态,它会是Modified,但是事实并非如此。这个例子很简单,但是它解释了为什么状态是表示实体和上下文间的关系而不是实体和数据库的关系。
当然,实体的状态影响它的持久化方式。这并不奇怪,当持久化实体时,在数据库中使用INSERT, UPDATE, 或DELETE命令保存那些Added,Modified或者Deleted状态。
实体状态如何影响数据库
状态不仅仅表示上下文中的实体状态,还表示数据如何持久化到数据库。每一个状态,都有一个对应的SQL命令。
Added状态的实体使用INSERT命令在映射的表中创建一个新行进行持久化。Modified实体在表中已经有了对应的行,所以使用UPDATE命令持久化。Deleted状态的实体在表中有对应的行,但是它触发DELETE而不是UPDATE。
Detached和Unchanged状态对数据库没有影响:detached实体不能被上下文追踪,所以不用持久化,而unchanged实体没有修改的东西需要持久化。
在其生存期期间,实体可以改变其状态。
实体生命周期的状态改变
实体的状态可以由上下文(context)自动设置也可以由开发人员手动设置。尽管从一个状态到另一个状态的所有转换组合都是可能的,但是有一些是没有意义的。例如,将一个实体从Added状态转换到Deleted状态是没有意义的,反之亦然。下图展示了所有的状态以及一个实体如何从一个状态传递到另一个状态。
图中描述的非常清晰了,唯一需要说明的就是图中所示的所有方法都属于ObjectContext或者ObjectSet<T>类。下面我们详细的看一下各种状态。
DETACHED状态
当一个实体处于Detached状态,它没有绑定到上下文(context),所以它的状态是不能被追踪的。它可以释放,修改以及和其他类组合或者其他任何你可能需要的方式使用。因为它没有上下文追踪它,它对EF没有意义。
由于上下文不能追踪你代码中任何对象的创建,因此,Detached是新创建实体的默认状态。即使你在上下文的using块中实例化实体也是如此。当追踪被禁用时,Detached还是从数据库中检索的实体的状态。
UNCHANGED状态
当实体是Unchanged状态,它被绑定到上下文,但是它还没有被修改。默认情况下,从数据库中检索的实体是这种状态。
当实体附加到(使用Attach方法)上下文时,它同样是Unchanged状态。上下文不能追踪它不引用的对象的变化,所以当它们附加到上下文,它们是Unchanged状态。
ADDED状态
当实体处于Added状态,你有很少的选择。实际上,你只能使用Detach方法将它从上下文中分离。
当然,即使你修改了一些属性,状态依然保持为Added,因为转换到Modified,Unchanged或者Deleted没有意义——它是一个新实体并且在数据库中没有对应的行。这是处在这些状态的前提条件。
MODIFIED状态
当实体是Modified时,这意味着它处在Unchanged状态,然后改变了一些属性。
一个实体进入Modified状态后,它可以转换到Detached或者Deleted状态,但是即使手动重置初始值也不能使它回滚到Unchanged状态(除非从上下文分离再附加到上下文)。它也不能变成Added状态(除非从上下文分离再添加一个实体到上下文,因为在数据库中已经存在这个ID的行,当持久化它时,就会得到一个运行时异常)。
DELETED状态
实体进入Deleted状态因为它处于Unchanged或者Modified状态,然后使用了DeleteObject。这是最严格的状态,因为除了转换成Detached状态,从这种状态转换成任何其他的状态都是没有意义的。
下一篇文章学习如何管理实体的状态。
Entity Framework 4 in Action读书笔记——第六章:理解实体的生命周期(一)相关推荐
- Entity Framework 4 in Action读书笔记——第六章:理解实体的生命周期(三)
objectstatemanager更改跟踪管理 ObjectStateManager组件(从现在开始称之为 state manager)负责与上下中对象追踪有关的一切: 1.当添加,附加到上下文或者 ...
- Entity Framework 4 in Action读书笔记——第三章:查询对象模型基础(1)
本章要点: 1.EF查询技术. 2.捕捉生成的SQL. 3.深入理解EF查询引擎. 4.常见的查询陷阱. 一.查询引擎入口点 对象服务层最重要的类是ObjectContext.在你的代码中它是最有用的 ...
- Entity Framework 4 in Action读书笔记——第四章:使用LINQ to Entities查询:使用函数...
4.7 使用函数 扩展LINQ to Entities查询的简便方法就是使用函数.有四种类型的函数可以应用: 规范函数-LINQ to Entities本身没有提供的一组预定义的函数. 数据库函数-一 ...
- Entity Framework 4 in Action读书笔记——第四章:使用LINQ to Entities查询:预先加载和延迟加载...
4.9 加载(Fetching) 预先加载指在一个查询中加载所有的实体和关联的数据.延迟加载指使用时再加载关联的实体.预先加载是检索数据最高效的方法.尽管它从数据库中检索所有的数据,但是只访问一次数据 ...
- Entity Framework 4 in Action读书笔记——第四章:使用LINQ to Entities查询:执行手动查询...
4.8 执行手动查询 有很多原因决定你会手动写查询.或许由EF生成的SQL太慢,又或许执行起来浪费了太多资源.另一种情况可能是当你动态生成一个如此复杂的查询,创建SQL代码比使用LINQ to Ent ...
- Entity Framework 4 in Action读书笔记——第四章:使用LINQ to Entities查询:排序和连接数据...
4.4排序(Sorting) 基本需求:用户想数据根据送货城市和邮政编码排序. 解决方案:知道LINQ有一个扩展方法可以根据一个或多个属性排序你一定会很高兴.LINQ to Entities提供了这个 ...
- Entity Framework 4 in Action 读书笔记——开篇
写在开篇之前 Entity Framework 4 In Action 这本书目前还没有中文版的,大体看了一下目录感觉还不错,如果想从中学到东西还是看原汁原味的好.从淘宝上搜了一下这本书要将近100块 ...
- Entity Framework 4 in Action读书笔记——第一章:数据访问重载:Entity Framework(2)...
上一篇讲解了通用数据容器,这一篇使用类来组织数据. 类是面向对象编程语言的基础.使用类,你不需要知道具体的存储机制,数据源可以是数据库,Web服务,XML文件等.类提供了很多优势,尤其是在企业应用中. ...
- Machine Learning in Action 读书笔记---第5章 Logistic回归
Machine Learning in Action 读书笔记 第5章 Logistic回归 文章目录 Machine Learning in Action 读书笔记 一.Logistic回归 1.L ...
最新文章
- shell 脚本中如何实现自加操作
- 字节Java高工面试:java软件开发工程师的市场薪资
- MySql 创建索引原则
- linux中find命令的35个实际例子
- springboot 单例_如何实现一个单例及优化
- 【词向量】从Word2Vec到Bert,聊聊词向量的前世今生(一)
- C/C++线程与多线程工作笔记003---C++指针引用和解引用
- IBM 确认裁员约 1700 人;华为新款操作系统来了!开通 5G 服务不换卡不换号 | 极客头条...
- python程序设计陈春晖答案_Python程序设计
- ff14个服务器位置,新人求推荐个服务器
- unity 裙子摆动_Unity中实现MMD效果
- postgresql数据库进行等保测评(审计) 需要修改的参数
- 京东准点秒杀脚本【2020】
- ISE WARNING:ProjectMgmt - File /*filePath*/ is missing.解决方法
- Drawable的setBounds方法
- 人生苦短,使用百度云SDK,编写python代码调用接口的车牌识别
- 知名密码管理应用LastPass启用双因素认证
- 怎么将pdf格式转换成jpg
- Vue移动端系列 => [07] 文章详情
- [矩阵计算]Lanczos方法:求稀疏矩阵特征值