当前位置: 首页 > news >正文

(26)ASP.NET Core2.2 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
        {
            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 '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.
  After deleting blog '1':
    Blog '1' is in state Deleted with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.
  Saving changes:
    DELETE FROM [Posts] WHERE [PostId] = 1
    DELETE FROM [Posts] WHERE [PostId] = 2
    DELETE FROM [Blogs] WHERE [BlogId] = 1
  After SaveChanges:
    Blog '1' is in state Detached with 2 posts referenced.
      Post '1' is in state Detached with FK '1' and no reference to a blog.
      Post '2' is in state Detached with FK '1' 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系列在这里也就完结了,暂时没有太多时间记录下去了。今天这个章节也偷了个懒,稍微精简一点,具体官方说明,我会在下面贴上的,请见谅。

参考文献:
基本保存https://learn.microsoft.com/zh-cn/ef/core/saving/basic
保存相关数据https://learn.microsoft.com/zh-cn/ef/core/saving/related-data
级联删除https://learn.microsoft.com/zh-cn/ef/core/saving/cascade-delete
使用事务https://learn.microsoft.com/zh-cn/ef/core/saving/transactions

http://www.rkmt.cn/news/20043.html

相关文章:

  • 2025 年国内脱硫剂生产厂家最新推荐排行榜:氧化铁 / 羟基氧化铁 / 常温氧化铁 / 沼气等多类型产品优质企业全方位解析
  • typora无需激活版及最新激活版方法!双击安装就能用
  • QPSK调制在瑞利、高斯和莱斯信道下的MATLAB仿真
  • uml总结
  • 在 2023 年屌爆了一整年的 shadcn/ui 用的 Headless UI 到底是何方神圣?
  • 2025 储能 EMS 厂商排名:五大品牌以全维度优势领跑,技术与规模双驱动企业凸显
  • [C++工程框架]gflags和gtest的简单介绍
  • 2025 最新活性炭交易服务公司排行榜:实力厂商与新锐品牌权威推荐,含选购指南
  • 制造业老牌汽配企业如何借助纷享销客CRM实现数字化转型?
  • idea使用记录
  • 2025年10月拉伸器批发厂家最新推荐排行榜,液压拉伸器,机械拉伸器,电动拉伸器公司推荐!
  • Gitee崛起:中国开发者生态的新基建如何重塑技术格局
  • Qwen2.5技术报告
  • 2025年10月变位机厂家最新推荐排行榜,焊接变位机,机器人变位机,重型变位机,轻型变位机公司推荐!
  • 【技术干货】Vaadin Flow vs Hilla:你该选择哪个Java Web框架?
  • 图解直接映射(Direct mapped)、全相联(Fully-associative)和组相联(Set-associative)cache缓存基本原理
  • 彩笔运维勇闯机器学习--KNN算法
  • 2025 年计数包装机厂家最新推荐榜:聚焦高精度高效能品牌,助力企业智能化生产升级全自动/种子/五金/注塑件/纽扣计数包装机厂家推荐
  • 2025 年蝶阀厂家最新推荐:全金属 / 高压 / 美标 / 双偏心 / 三偏心等各类蝶阀优质厂家榜单及选择指南
  • DevExpress WPF中文教程:Data Grid - 如何使用虚拟源?(一)
  • wqs二分学习笔记
  • Android系统中使用initrc脚本在开机时禁用selinux
  • 2025年10月氧化镁厂家最新推荐排行榜,轻烧氧化镁,重烧氧化镁,高纯氧化镁,活性氧化镁公司推荐!
  • Vector向量数据库对比
  • 2025 年最新推荐集装箱拖车供应厂家权威榜单:全方位解析优质企业实力,助力精准选择箱式 / 冷藏等拖车服务
  • 2025 最新铝型材源头厂家推荐排行榜:优选企业深度解析,佛山龙头与新锐品牌选购指南
  • 行业推荐:广州智建云工程管理软件/软件系统/软件App/软件平台/工程管理软件和验房系统公司获认可,专业方案成品质管控优选
  • 2025 聚合氯化铝厂家最新推荐榜:优质厂家选购指南与高口碑品牌全解析聚合氯化铝絮凝剂/水处理用聚合氯化铝/生产聚合氯化铝厂家推荐
  • Java 集合框架详解
  • Except 脚本免密登录(带参数调用except脚本)