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保存(基本保存、保存相关数据、级联删除、使用事务)的更多相关文章

  1. asp.net core+ef core

    asp.net core+ef core 官方的文档https://docs.asp.net/en/latest/tutorials/first-mvc-app/start-mvc.html 先来看一 ...

  2. C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现之方法二:加入缓存机制

    在上一篇文章中我用递归方法实现了管理菜单,在上一节我也提到要考虑用缓存,也算是学习一下.Net Core的缓存机制. 关于.Net Core的缓存,官方有三种实现: 1.In Memory Cachi ...

  3. Asp.net Core + EF Core + Bootstrap搭建的MVC后台通用管理系统模板(跨平台版本)

    Asp.net Core + EF Core + Bootstrap搭建的MVC后台通用管理系统模板(跨平台版本) 原创 2016年07月22日 10:33:51 23125 6月随着.NET COR ...

  4. asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密。

    原文:asp.net core 使用中间件拦截请求和返回数据,并对数据进行加密解密. GitHub demo https://github.com/zhanglilong23/Asp.NetCore. ...

  5. Asp.net Core中使用Redis 来保存Session, 读取配置文件

    今天 无意看到Asp.net Core中使用Session ,首先要使用Session就必须添加Microsoft.AspNetCore.Session包,默认Session是只能存去字节,所以如果你 ...

  6. C#无限极分类树-创建-排序-读取 用Asp.Net Core+EF实现

    今天做一个管理后台菜单,想着要用无限极分类,记得园子里还是什么地方见过这种写法,可今天找了半天也没找到,没办法静下心来自己写了: 首先创建节点类(我给它取名:AdminUserTree): /// & ...

  7. ASP.NET Core&EF 笔记

    首先创建Asp.net Core项目,然后通过 NuGet 安装 EntityFrameworkCore: Microsoft.EntityFrameworkCore.SqlServer Micros ...

  8. (17)ASP.NET Core EF基于数据模型创建数据库

    1.简介 使用Entity Framework Core构建执行基本数据访问的ASP.NET Core MVC应用程序.使用迁移(Migrations)基于数据模型创建数据库,你可以在Windows上 ...

  9. ASp.net Core EF ActionFilterAttribute AOP

    在项目中经常遇到一些数据的修改,很多时候业务方需要一个修改日志记录,这里我们计划用mssql数据库来存放日志记录,用EF来操作,记录日志可以用mvc的ActionFilterAttribute 来完成 ...

随机推荐

  1. Revit二次开发-获取材质的纹理贴图

    通过IExportContext导出类中的Onmaterial()方法,可以获取到材质相关信息,主要是材质ID,再根据材质ID得到材质对象material,然后通过如下代码获取Asset对象: Ele ...

  2. 正则表达式sed学习(二)

    sedsed是一个流编辑器,非交互式的编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space)接着用 sed 命令处理缓冲区的内容,处理完成 ...

  3. 简单标签 SimpleTagSupport示例

    最近处理JSP页面,需要把数据库查到的原始值,根据数据字典转换成更加直观的值.比如查到的结果是 01,jsp页面展示‘身份证’. 如果值比较少,就直接用c:if标签处理了,无奈接触的值比较多,只想到了 ...

  4. 查询AD中被锁定的账号并进行解锁

    1:查询AD中被锁定的账号: Search-ADAccount -LockedOut | export-csv -path c:\aaavvv.csv 2:解除锁定 Search-ADAccount ...

  5. 对《java程序员上班那点事》笔者对数组占用内存质疑

    1.<java程序员上班那点事>笔者对数组占用内存的描述 2.实际测试情况: /** * 测试一维数组占用内存 */ public static void testOneArray() { ...

  6. OA|开放获取期刊|掠夺性期刊|DOI|ORCID|图书馆服务|零次文献|信息素质|

    OA|开放获取期刊|掠夺性期刊|DOI|ORCID|图书馆服务|零次文献| 信息检索 信息素质是什么? 信息素质是指一个人的信息需求.信息意识.信息知识.信息道德.信息能力方面的基本素质. Some ...

  7. c中结构体边界对齐

    原则1.普通数据成员对齐规则:第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储). 原则2 ...

  8. Luogu1681_ 最大正方形II

    题目背景 忙完了学校的事,v神终于可以做他的"正事":陪女朋友散步.一天,他和女朋友走着走着,不知不觉就来到了一个千里无烟的地方.v神正要往回走,如发现了一块牌子,牌子上有有一行小 ...

  9. js join()

    在本例中,我们将创建一个数组,然后把它的所有元素放入一个字符串: <script type="text/javascript"> var arr = new Array ...

  10. 安装NSQ

    安装文档 https://nsq.io/deployment/installing.html 打开连接后,根据系统找到对应的二进制包 一般都是linux则下载 https://s3.amazonaws ...