Entity Framework入门教程(10)---离线场景保存和删除实体/实体图集
离线场景保存和删除实体/实体图集
这一节的内容是在离线场景中保存实体和实体图集
在离线场景中,当我们保存一个离线的实体图集或一个单独的离线实体时,我们需要做两件事。首先,我们要把实体附加到新的上下文中,让上下文了知道存在这些实体。其次,我们需要手动设置每个实体的EntityState,因为新的上下文不知道这些离线实体都经过了些什么操作,所以新的上下文不能自动地给实体添加EntityState。上一节我们清楚了附加离线图集的方法,附加离线图集时默认添加的EntityState不一定合适,所以我们就要执行第二步:给实体或实体图集添加合适的EntityState。
1.离线场景中保存实体
在离线场景中我们保存一个实体时,最核心的问题:我们需要知道一个实体是新建的还是本来就存在的。只有知道了这个问题的答案,我们才能给实体设置EntityState。如果实体主键值是0(主键是Int类型,默认值为0)我们认为这个实体是新建的,给它的状态标记为Added;如果主键值大于0,那么我们就认为这个实体是已经存在的,将它的状态标记为Modified。如下图所示:
下边是一个栗子:
// 新建的离线实体
var student = new Student(){ StudentName = "Bill" }; using (var context = new SchoolDBEntities())
{
context.Entry(student).State = student.StudentId == ? EntityState.Added : EntityState.Modified; context.SaveChanges();
}
因为Student是新建的,Id默认为0,所以Student被标记为Added,在数据库中执行:
exec sp_executesql N'INSERT [dbo].[Student]([StudentName], [StandardId])
VALUES (@0, NULL)
SELECT [StudentID] FROM [dbo].[Student]
WHERE @@ROWCOUNT > 0 AND [StudentID] = scope_identity(),@0='Bill'
同样的,如果一个实体的主键不是0,那么将它的状态被标记为Modified,一个栗子:
// 虽然是新建的,但是因为Id不是0,所以EF认为是已存在的
var student = new Student(){ StudentId = , StudentName = "Steve" }; using (var context = new SchoolDBEntities())
{
context.Entry(student).State = student.StudentId == ? EntityState.Added : EntityState.Modified; context.SaveChanges();
}
在数据库中执行如下代码,注意:如果数据库中没有StudentId 为1的记录时,会报异常
exec sp_executesql N'UPDATE [dbo].[Student]
SET [StudentName] = @0
WHERE @@ROWCOUNT > 0 AND [StudentID] = @1'N'@0 varchar(50),@1 int',@0='Steve',@1=1
2.离线场景中保存实体图集
上边部分我们学习了通过主键值来设置实体的状态,这里我们将学习怎么去保存一个实体图集。
在离线场景中保存一个实体图集是一件比较复杂的事,我们需要进行认真的设计。离线场景中保存实体图集最需要解决的问题是给实体图集中的每一个实体添加标记适当的状态。但是怎么去设计呢?在下图中我们可以看到新的Context根本不知道每个实体的状态。
我们必须在执行SaveChange()方法前确定每一个实体的状态,下边介绍通过主键设置实体图集状态的方法
通过主键设置实体图集的状态
我们可以通过主键来设置实体图集中每一个实体的状态。如前边保存实体时介绍的,如果一个实体的主键是CLR数据类型的默认值(如int类型的默认值是0),那么我们认为这个实体是新建的,可以将这个实体标记为Added,在数据库执行Insert命令;如果主键值不是CLR数据类型的默认值,我们认为这个实体是已经存在了,标记为Modified,在数据库执行Update命令。
一个栗子:
var student = new Student() { //Root entity (没有主键值
Standard = new Standard() //Child entity (有主键值)
{
StandardId = ,
StandardName = "Grade 1"
},
Courses = new List<Course>() {
new Course(){ CourseName = "Machine Language" }, //Child entity (没有主键值)
new Course(){ CourseId = } //Child entity (有主键值)
}
}; using (var context = new SchoolDBEntities())
{
//给实体图集中的所有实体的状态进行标记
context.Entry(student).State = student.StudentId == ? EntityState.Added : EntityState.Modified; context.Entry(student.Standard).State = student.Standard.StandardId == ? EntityState.Added : EntityState.Modified; foreach (var course in student.Courses)
context.Entry(course).State = course.CourseId == ? EntityState.Added : EntityState.Modified; context.SaveChanges();
}
在上边的栗子中,Student实体图集包含Standard和Course实体,context通过每个实体的主键对该实体的状态进行标记。
3.离线场景删除实体/实体图集
在离线场景删除一个实体很简单,只需通过Entry()方法把实体的状态标记为Deleted即可,注:我们在将离线实体附加到上下文提过,当父实体的状态是Deleted时,通过Entry()方法附加实体图集时,实体图集的所有子实体都为null,所以在执行SaveChange()进行数据库删除时,只删除父实体的记录!一个简单的栗子:
// 待删除的实体
var student = new Student(){ StudentId = }; using (var context = new SchoolDBEntities())
{
context.Entry(student).State = System.Data.Entity.EntityState.Deleted;
context.SaveChanges();
}
在上边的例子中,Student实体的实例只有主键值,删除一个实体也只需要主键值就可以了。在数据库中执行如下代码:
delete [dbo].[Student]
where ([StudentId] = @0)',N'@0 int',@0=1
EF系列目录链接:Entity Franmework系列教程汇总
Entity Framework入门教程(10)---离线场景保存和删除实体/实体图集的更多相关文章
- Entity Framework入门教程(9)---离线场景附加实体图集到上下文
附加离线实体图集到上下文 这节主要内容是通过不同的方法将离线实体附加到上下文中. 在离线场景中,保存一个实体要略微困难一些.当我们保存一个离线的实体图集或一个单独的离线实体时,我们需要做两件事.首先, ...
- Entity Framework入门教程(6)--- 在线场景中保存数据
在线场景中保存数据 在线场景中保存实体数据是一项相当容易的任务,因为使用的是同一个context,这个context会自动跟踪所有实体发生的更改. 下图说明了在线场景中的CUD(创建,更新,删除)操作 ...
- Entity Framework入门教程(5)---EF中的持久化场景
EF中的持久性场景 使用EF实现实体持久化(保存)到数据库有两种情况:在线场景和离线场景. 1.在线场景 在线场景中,context是同一个上下文实例(从DbContext派生),检索和保存实体都通过 ...
- Entity Framework入门教程(11)---EF6中的异步查询和异步保存
EF6中的异步查询和异步保存 在.NET4.5中介绍了异步操作,异步操作在EF中也很有用,在EF6中我们可以使用DbContext的实例进行异步查询和异步保存. 1.异步查询 下边是一个通过L2E语法 ...
- Entity Framework入门教程(1)---Entity Framework简介
什么是Entity Framework 学习EF的前提:熟练使用Linq和Ado.net,因为在使用EF框架进行开发时,我们大多数情况使用Linq进行查询和操作,而EF的底层实现用的是Ado.net. ...
- Entity Framework入门教程:什么是Entity Framework
Entity Framework简介 Entity Framework是微软提供的一个O/RM(对象关系映射)框架.它基于ADO.NET,为开发人员提供了一种自动化的机制来访问和存储数据库中的数据. ...
- Entity Framework入门教程(2)---EF工作流程
EF工作流程 1.EF基本CRUD流程 下边的图就可以很清晰地展示EF的CRUD操作的基本工作流程: 这里做一个EF CRUD操作的简单总结:1.定义模型:这是EF工作的前提,定义模型包括定义领域类( ...
- Entity Framework入门教程(13)---EF中的高并发
EF中的高并发 这里只介绍EF6中database-first开发方案的高并发解决方案,code-first开发方案中的高并发会在以后的EF CodeFirst系列中介绍. EF默认支持乐观并发:我们 ...
- ASP .NET MVC 之Entity Framework入门教程及源码
本文主要的目的是 1. 说明Entity Framework Power Tools如何使用. 2. Entity Framework 快速门 实验环境: OS: Windows Server 20 ...
随机推荐
- 利用ZYNQ SOC快速打开算法验证通路(5)——system generator算法IP导入IP integrator
一.前言 利用FPGA设计算法一直以来都是热点,同样也是难点.将复杂的数学公式 模型通过硬件系统来搭建,在低延时 高并行性等优势背后极大提高了设计难度和开发周期.Xilinx公司的sysGen(sys ...
- mybatis使用oracle的sequence
oracle数据库创建SEQUENCE CREATE SEQUENCE SEQ_COM_MASTER START INCREMENT MINVALUE MAXVALUE NOCYCLE CACHE ; ...
- SQLServer之DEFAULT约束
DEFAULT约束添加规则 1.若在表中定义了默认值约束,用户在插入新的数据行时,如果该行没有指定数据,那么系统将默认值赋给该列,如果我们不设置默认值,系统默认为NULL. 2.如果“默认值”字段中的 ...
- MySQL 5.7.13 的一个BUG
mysql今天从5.6切到5.7,在测试环境中,日志是全部打印的,发现打了一个警告: Incorrect string value: '\xD6\xD0\xB9\xFA\xB1\xEA...' for ...
- 【Shell基础】字符串删除
案例:将金额18.中的点去掉,结果为18 #!/bin/shold_value=. new_value=`echo ${old_value%%.*}` echo $new_value ${filena ...
- CSS伪元素:before/CSS伪元素:before/:after content 显示Font Awesome字体图标:after content 显示Font Awesome字体图标
HTML <a href="javascript:volid(0);"><i class="icon-table"></i> ...
- centos7下kubernetes(18。kubernetes-健康检查)
自愈能力是容器的重要特性.自愈的默认方式是自动重启发生故障的容器. 用户还可以通过liveness和readiness探测机制设置更精细的健康检查,进而实现: 1.零停机部署 2.避免部署无效的镜像 ...
- php常用数组array函数实例总结【赋值,拆分,合并,计算,添加,删除,查询,判断,排序】
本文实例总结了php常用数组array函数.分享给大家供大家参考,具体如下: array_combine 功能:用一个数组的值作为新数组的键名,另一个数组的值作为新数组的值 案例: <?php ...
- Linux内核入门到放弃-页缓存和块缓存-《深入Linux内核架构》笔记
内核为块设备提供了两种通用的缓存方案. 页缓存(page cache) 块缓存(buffer cache) 页缓存的结构 在页缓存中搜索一页所花费的时间必须最小化,以确保缓存失效的代价尽可能低廉,因为 ...
- redis 初步认识一(下载安装redis)
1.下载redis https://github.com/MicrosoftArchive/redis/releases 2.开启redis服务 3.使用redis 4.redis可视化工具 一 开 ...