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 ...
随机推荐
- 高德地图 Service 创建服务 USERKEY_PLAT_NOMATCH
在使用高的地图 创建服务的时候 { "errmsg": "USERKEY_PLAT_NOMATCH", "errcode": 10009, ...
- Docker之常用命令(二)
这篇博客就不扯皮了,简单粗暴地贴上自己整理的一份Docker常用命令. docker search ** // 查找镜像 docker pull nginx // 载入镜像 # -a 拉取所有tagg ...
- JavaScript 面向对象之原型对象
原型的概述 我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法. 逻辑上可以这么理解:prototype 通过调用构 ...
- [LeetCode] 9. 回文数
题目链接:https://leetcode-cn.com/problems/palindrome-number/ 题目描述: 判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都 ...
- loadrunner迭代和并发的区别
转载: ZEE的回答: 用比喻的方式来回一下: 四车道的马路,如果只有四辆车并排走过就是并发: 如果四辆车排成一纵队走过就是迭代: 如果有100辆车排成25行依次走过就是并发加迭代. 在以上说法中,只 ...
- C++笔记--std::相关
std::packaged_task https://www.cnblogs.com/haippy/p/3279565.html https://en.cppreference.com/w/cpp/t ...
- 错误:set Assigning an instance of 'esri.***' which is not a subclass of 'esri.***‘
1. 出现 set Assigning an instance of 'esri.***' which is not a subclass of 'esri.***‘的错误原因 是 因为没有找见 ...
- USB安装centos6系统(centos7需要换软件)
一.下载系统镜像 二.下载安装软碟通软件UltraISO 三.插入U盘制作启动盘 1.用软碟通打开镜像文件:文件-->打开 2.写入映像:启动-->写入硬盘映像 3.等待写入完成 四.系统 ...
- "unexpected console statement” in Node.js
.eslintrc.js module.exports = { rules: { 'no-console': 'off', }, };
- Python——入门 | 常用python实现
一.冒泡排序 list = [56,12,1,8,354,10,100,34,56,7,23,456,234,-58] def MP_paixu(): for i in range(len(list) ...