(26)ASP.NET Core EF保存(基本保存、保存相关数据、级联删除、使用事务)
1.简介
每个上下文实例都有一个ChangeTracker,它负责跟踪需要写入数据库的更改。更改实体类的实例时,这些更改会记录在ChangeTracker中,然后在调用SaveChanges时会被写入数据库中。此数据库提供程序负责将更改转换为特定于数据库的操作(例如,关系数据库的INSERT、UPDATE和DELETE命令)。
2.基本保存
了解如何使用上下文和实体类添加、修改和删除数据。
2.1添加数据
使用DbSet.Add方法添加实体类的新实例。调用SaveChanges时,数据将插入到数据库中。
using (var context = new BloggingContext())
{
var blog = new Blog { Url = "http://sample.com" };
context.Blogs.Add(blog);
context.SaveChanges();
}
2.2更新数据
EF将自动检测对由上下文跟踪的现有实体所做的更改。这包括从数据库加载查询的实体,以及之前添加并保存到数据库的实体。只需通过赋值来修改属性,然后调用SaveChanges即可。
using (var context = new BloggingContext())
{
var blog = context.Blogs.First();
blog.Url = "http://sample.com/blog";
context.SaveChanges();
}
2.3删除数据
使用DbSet.Remove方法删除实体类的实例。如果实体已存在于数据库中,则将在SaveChanges期间删除该实体。如果实体尚未保存到数据库(即跟踪为“已添加”),则在调用SaveChanges时,该实体会从上下文中移除且不再插入。
using (var context = new BloggingContext())
{
var blog = context.Blogs.First();
context.Blogs.Remove(blog);
context.SaveChanges();
}
2.4单个SaveChanges中的多个操作
可以将多个添加/更新/删除操作合并到对SaveChanges的单个调用。
using (var context = new BloggingContext())
{
// add
context.Blogs.Add(new Blog { Url = "http://sample.com/blog_one" });
context.Blogs.Add(new Blog { Url = "http://sample.com/blog_two" });
// update
var firstBlog = context.Blogs.First();
firstBlog.Url = "";
// remove
var lastBlog = context.Blogs.Last();
context.Blogs.Remove(lastBlog);
context.SaveChanges();
}
3.保存关联数据
除了独立实体以外,还可以使用模型中定义的关系。
3.1添加关联数据
如果创建多个新的相关实体,则将其中一个添加到上下文时也会添加其他实体。在下面的示例中,博客和三个相关文章会全部插入到数据库中。找到并添加这些文章,因为它们可以通过Blog.Posts导航属性访问。
using (var context = new BloggingContext())
{
var blog = new Blog
{
Url = "http://blogs.msdn.com/dotnet",
Posts = new List<Post>
{
new Post { Title = "Intro to C#" },
new Post { Title = "Intro to VB.NET" },
new Post { Title = "Intro to F#" }
}
};
context.Blogs.Add(blog);
context.SaveChanges();
}
3.2添加相关实体
如果从已由上下文跟踪的实体的导航属性中引用新实体,则将发现该实体并将其插入到数据库中。在下面的示例中,插入post实体,因为该实体会添加到已从数据库中提取的blog实体的Posts属性。
using (var context = new BloggingContext())
{
var blog = context.Blogs.Include(b => b.Posts).First();
var post = new Post { Title = "Intro to EF Core" };
blog.Posts.Add(post);
context.SaveChanges();
}
3.3更改关系
如果更改实体的导航属性,则将对数据库中的外键列进行相应的更改。在下面的示例中,post实体更新为属于新的blog实体,因为其Blog导航属性设置为指向blog,blog也会插入到数据库中,因为它是已由上下文post跟踪的实体的导航属性引用的新实体。
using (var context = new BloggingContext())
{
//新增一个主体实体
var blog = new Blog { Url = "http://blogs.msdn.com/visualstudio" };
var post = context.Posts.First();
//post更新关系
post.Blog = blog;
context.SaveChanges();
}
4.级联删除
删除行为在DeleteBehavior枚举器类型中定义,并且可以传递到OnDelete Fluent API来控制:
●可以删除子项/依赖项
●子项的外键值可以设置为null
●子项保持不变
示例:
var blog = context.Blogs.Include(b => b.Posts).First();
var posts = blog.Posts.ToList();
DumpEntities(" After loading entities:", context, blog, posts);
context.Remove(blog);
DumpEntities($" After deleting blog '{blog.BlogId}':", context, blog, posts);
try
{
Console.WriteLine();
Console.WriteLine(" Saving changes:");
context.SaveChanges();
DumpSql();
DumpEntities(" After SaveChanges:", context, blog, posts);
}
catch (Exception e)
{
DumpSql();
Console.WriteLine();
Console.WriteLine($" SaveChanges threw {e.GetType().Name}: {(e is DbUpdateException ? e.InnerException.Message : e.Message)}");
}
记录结果:
After loading entities:
Blog '' is in state Unchanged with posts referenced.
Post '' is in state Unchanged with FK '' and reference to blog ''.
Post '' is in state Unchanged with FK '' and reference to blog ''. After deleting blog '':
Blog '' is in state Deleted with posts referenced.
Post '' is in state Unchanged with FK '' and reference to blog ''.
Post '' is in state Unchanged with FK '' and reference to blog ''. Saving changes:
DELETE FROM [Posts] WHERE [PostId] =
DELETE FROM [Posts] WHERE [PostId] =
DELETE FROM [Blogs] WHERE [BlogId] = After SaveChanges:
Blog '' is in state Detached with posts referenced.
Post '' is in state Detached with FK '' and no reference to a blog.
Post '' is in state Detached with FK '' and no reference to a blog.
5.事务
事务允许以原子方式处理多个数据库操作。如果已提交事务,则所有操作都会成功应用到数据库。如果已回滚事务,则所有操作都不会应用到数据库。
5.1控制事务
可以使用DbContext.Database API开始、提交和回滚事务。以下示例显示了两个SaveChanges()操作以及正在单个事务中执行的LINQ查询。并非所有数据库提供应用程序都支持事务的。 调用事务API时,某些提供应用程序可能会引发异常或不执行任何操作。
using (var context = new BloggingContext())
{
using (var transaction = context.Database.BeginTransaction())
{
try
{
context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/dotnet" });
context.SaveChanges();
context.Blogs.Add(new Blog { Url = "http://blogs.msdn.com/visualstudio" });
context.SaveChanges();
var blogs = context.Blogs
.OrderBy(b => b.Url)
.ToList();
// Commit transaction if all commands succeed, transaction will auto-rollback
// when disposed if either commands fails
transaction.Commit();
}
catch (Exception)
{
// TODO: Handle failure
}
}
}
6.总结
由于工作繁忙原因,EF系列在这里也就完结了,暂时没有太多时间记录下去了。今天这个章节也偷了个懒,稍微精简一点,具体官方说明,我会在下面贴上的,请见谅。
(26)ASP.NET Core EF保存(基本保存、保存相关数据、级联删除、使用事务)的更多相关文章
- asp.net core+ef core
asp.net core+ef core 官方的文档https://docs.asp.net/en/latest/tutorials/first-mvc-app/start-mvc.html 先来看一 ...
- C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现之方法二:加入缓存机制
在上一篇文章中我用递归方法实现了管理菜单,在上一节我也提到要考虑用缓存,也算是学习一下.Net Core的缓存机制. 关于.Net Core的缓存,官方有三种实现: 1.In Memory Cachi ...
- Asp.net Core + EF Core + Bootstrap搭建的MVC后台通用管理系统模板(跨平台版本)
Asp.net Core + EF Core + Bootstrap搭建的MVC后台通用管理系统模板(跨平台版本) 原创 2016年07月22日 10:33:51 23125 6月随着.NET COR ...
- asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密。
原文:asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密. GitHub demo https://github.com/zhanglilong23/Asp.NetCore. ...
- Asp.net Core中使用Redis 来保存Session, 读取配置文件
今天 无意看到Asp.net Core中使用Session ,首先要使用Session就必须添加Microsoft.AspNetCore.Session包,默认Session是只能存去字节,所以如果你 ...
- C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现
今天做一个管理后台菜单,想着要用无限极分类,记得园子里还是什么地方见过这种写法,可今天找了半天也没找到,没办法静下心来自己写了: 首先创建节点类(我给它取名:AdminUserTree): /// & ...
- ASP.NET Core&EF 笔记
首先创建Asp.net Core项目,然后通过 NuGet 安装 EntityFrameworkCore: Microsoft.EntityFrameworkCore.SqlServer Micros ...
- (17)ASP.NET Core EF基于数据模型创建数据库
1.简介 使用Entity Framework Core构建执行基本数据访问的ASP.NET Core MVC应用程序.使用迁移(Migrations)基于数据模型创建数据库,你可以在Windows上 ...
- ASp.net Core EF ActionFilterAttribute AOP
在项目中经常遇到一些数据的修改,很多时候业务方需要一个修改日志记录,这里我们计划用mssql数据库来存放日志记录,用EF来操作,记录日志可以用mvc的ActionFilterAttribute 来完成 ...
随机推荐
- Idea mac
Idea 的破解 http://idea.lanyus.com/ Idea 的常用配置 模版及模版的使用 创建 JavaWeb 或 Module 关联数据库 版本控制 断点调试 配置 maven 其他 ...
- Web Service概述 及 应用案例
Web Service的定义 W3C组织对其的定义如下,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计.Web Service服务通常被定义为一组模块化的API,它们可以通过网络进行调用 ...
- UFT参数化
1.Resources-Record and Run Settings 2.打开程序进行录制操作 3.对Fly from和Fly to进行参数化 4.选中点击 5.输入名称,点击OK 6.在Data加 ...
- javascript中的undefined 和 not defined
经研究发现,两者之间有很大的区别,不知从英语讲,这两者都有啥区别,研究结果如下 测试os:ubuntu 测试浏览器:chrome 测试案例1 console.log(a) 报错 ReferenceEr ...
- 获取指定网卡对应的IP地址
#include <stdio.h> #include <string.h> #include <sys/socket.h> #include <sys/ty ...
- ffmpeg直播系统
1.HLS协议 http live streaming 将本地文件或者摄像头视频转成hls流文件 https://www.ffmpeg.org/ffmpeg-all.html#hls-2 2.rtmp ...
- 吴裕雄--天生自然python学习笔记:python爬虫与网页分析
我们所抓取的网页源代码一般都是 HTML 格式的文件,只要研究明白 HTML 中 的标签( Tag )结构,就很容易进行解析并取得所需数据 . HTML 网页结构 HTML 网 页是由许多标签( Ta ...
- SpringMVC源码剖析2——处理器映射器
1.处理器映射器 HandlerMapping 一句话概括作用: 为 我 们 建 立 起 @RequestMapping 注 解 和 控 制 器 方 法 的 对 应 关 系 . 怎么去查看 第一步: ...
- openssl编译时!遇见的问题
openssl编译: 1.编译静态库 ./config --prefix=/root/openssl/soft make 2.编译动态库 ./config --prefix=/root/openssl ...
- top100 paper