广告
返回顶部
首页 > 资讯 > 精选 >如何进行Entity Framework Core关联删除
  • 849
分享到

如何进行Entity Framework Core关联删除

2023-06-22 07:06:29 849人浏览 八月长安
摘要

这篇文章将为大家详细讲解有关如何进行Entity Framework Core关联删除,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。关联删除通常是一个数据库术语,用于描述

这篇文章将为大家详细讲解有关如何进行Entity Framework Core关联删除,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

关联删除通常是一个数据库术语,用于描述在删除行时允许自动触发删除关联行的特征;即当主表的数据行被删除时,自动将关联表中依赖的数据行进行删除,或者将外键更新为NULL或默认值。

数据库关联删除行为

我们先来看一看SQL Server中支持的行为。在创建外键约束时,可以指定关联表在主表删除行时,对依赖的数据如何执行操作。例如下面的sql语句,[Order Details]表中[OrderID]字段 是外键,依赖于[Orders]表中的主键[OrderID]。

CREATE TABLE [Orders] (    [OrderID] int NOT NULL IDENTITY,    [Name] nvarchar(max) NULL,    [OrderDate] datetime2 NULL,    CONSTRAINT [PK_Orders] PRIMARY KEY ([OrderID]));GoCREATE TABLE [Order Details] (    [DetailId] int NOT NULL IDENTITY,    [OrderID] int NULL,    [ProductID] int NOT NULL,    CONSTRAINT [PK_Order Details] PRIMARY KEY ([DetailId]),    CONSTRAINT [FK_Order Details_Orders_OrderID] FOREIGN KEY ([OrderID]) REFERENCES [Orders] ([OrderID]) ON DELETE SET NULL);

外键约束[FK_Order Details_Orders_OrderID]末尾的语句是ON DELETE SET NULL,表示当主表的数据行删除时,自动将关联表数据行的外键更新为NULL。

在SQL Server中支持如下四种行为:

ON DELETE NO ACTioN

默认行为,删除主表数据行时,依赖表中的数据不会执行任何操作,此时会产生错误,并回滚DELETE语句。例如会产生下面的错误:

DELETE 语句与 REFERENCE 约束"FK_Order Details_Orders_OrderID"冲突。该冲突发生于数据库"Northwind_Test",表"dbo.Order Details", column 'OrderID'。

语句已终止。

ON DELETE CASCADE

删除主表数据行时,依赖表的中数据行也会同步删除。

ON DELETE SET NULL

删除主表数据行时,将依赖表中数据行的外键更新为NULL。为了满足此约束,目标表的外键列必须可为空值。

ON DELETE SET DEFAULT

删除主表数据行时,将依赖表的中数据行的外键更新为默认值。为了满足此约束,目标表的所有外键列必须具有默认值定义;如果外键可为空值,并且未显式设置默认值,则将使用NULL作为该列的隐式默认值。

简单介绍了数据库中行为后,我们来着重介绍 EF Core 中的关联实体的行为。

定义实体

我们先定义两个实体Order、OrderDetail分别表示订单和订单明细;其中Order与OrderDetail的关系是一对多,在OrderDetail实体中OrderID表示外键,依赖于Order实体中的主键OrderID。

public class Order    {        public int OrderID { get; set; }        public string Name { get; set; }        public DateTime? OrderDate { get; set; }        public ICollection<OrderDetail> OrderDetails { get; set; }    }    public class OrderDetail    {        public int DetailId { get; set; }        public int? OrderID { get; set; }                public int ProductID { get; set; }        public Order Order { get; set; }    }

Fluent api 配置关联实体

在DbContext中OnModelCreating方法中,我们使用 Fluent API 配置实体中之间的关系。

public class NorthwindContext : DbContext    {        public virtual DbSet<Order> Orders { get; set; }        public virtual DbSet<OrderDetail> OrderDetails { get; set; }        protected override void OnModelCreating(ModelBuilder modelBuilder)        {            modelBuilder.Entity<Order>(                builder =>                {                    builder.HasMany<OrderDetail>(e => e.OrderDetails).WithOne(e => e.Order).HasForeignKey(e => e.OrderID).OnDelete(DeleteBehavior.ClientSetNull);                });        }    }

在OnDelete方法中,需要传递参数DeleteBehavior枚举,分别有如下四个值:

public enum DeleteBehavior    {        Cascade,        SetNull,        ClientSetNull,        Restrict    }

这四个枚举值的分别表示不同的行为,这也是我们今天的重点。

创建表结构

我们分别使用使用这这个枚举值,来创建数据表结构。

[InlineData(DeleteBehavior.Cascade)]        [InlineData(DeleteBehavior.SetNull)]         [InlineData(DeleteBehavior.ClientSetNull)]        [InlineData(DeleteBehavior.Restrict)]        [Theory]        public void Create_Database(DeleteBehavior behavior)        {            using (var northwindContext = new NorthwindContext(behavior))            {                northwindContext.Database.EnsureDeleted();                northwindContext.Database.EnsureCreated();            }        }

四个枚举值创建表的SQL语句类似如下,唯一区别在于创建外键约束[FK_Order Details_Orders_OrderID]中ON DELETE {}后面的语句。

CREATE TABLE [Orders] (    [OrderID] int NOT NULL IDENTITY,    [Name] nvarchar(max) NULL,    [OrderDate] datetime2 NULL,    CONSTRAINT [PK_Orders] PRIMARY KEY ([OrderID]));GOCREATE TABLE [Order Details] (    [DetailId] int NOT NULL IDENTITY,    [OrderID] int NOT NULL,    [ProductID] int NOT NULL,    CONSTRAINT [PK_Order Details] PRIMARY KEY ([DetailId]),    CONSTRAINT [FK_Order Details_Orders_OrderID] FOREIGN KEY ([OrderID]) REFERENCES [Orders] ([OrderID]) ON DELETE CASCADE);

四个枚举值分别对应的SQL语句如下:

如何进行Entity Framework Core关联删除

EF Core 关联实体删除行为

我们分别通过枚举值与是否跟踪关联实体,进行代码测试,测试代码如下:

[InlineData(DeleteBehavior.Cascade, true)]        [InlineData(DeleteBehavior.Cascade, false)]        [InlineData(DeleteBehavior.SetNull, true)]        [InlineData(DeleteBehavior.SetNull, false)]        [InlineData(DeleteBehavior.ClientSetNull, true)]        [InlineData(DeleteBehavior.ClientSetNull, false)]        [InlineData(DeleteBehavior.Restrict, true)]        [InlineData(DeleteBehavior.Restrict, false)]        [Theory]        public void Execute(DeleteBehavior behavior, bool includeDetail)        {            using (var northwindContext = new NorthwindContext(behavior))            {                northwindContext.Database.EnsureDeleted();                northwindContext.Database.EnsureCreated();            }            int orderId;            int detailId;            using (var northwindContext = new NorthwindContext(behavior))            {                var order = new Order {                    Name = "Order1"                };                var orderDetail = new OrderDetail {                    ProductID = 11                };                order.OrderDetails = new List<OrderDetail> {                    orderDetail                };                northwindContext.Set<Order>().Add(order);                                northwindContext.SaveChanges();                orderId = order.OrderID;                detailId = orderDetail.DetailId;            }            using (var northwindContext = new NorthwindContext(behavior))            {                var queryable = northwindContext.Set<Order>().Where(e => e.OrderID == orderId);                if (includeDetail){                    queryable = queryable.Include(e => e.OrderDetails);                }                var order = queryable.Single();                 northwindContext.Set<Order>().Remove(order);                try                {                    northwindContext.SaveChanges();                    DumpSql();                }                catch (Exception)                {                    DumpSql();                    throw;                }            }            using (var northwindContext = new NorthwindContext(behavior))            {                var orderDetail = northwindContext.Set<OrderDetail>().Find(detailId);                if (behavior == DeleteBehavior.Cascade)                {                    Assert.Null(orderDetail);                }                else                {                    Assert.NotNull(orderDetail);                }            }        }

如何进行Entity Framework Core关联删除        

总结

根据上面的测试结果,我们可以出得如下结论:

DeleteBehavior.Cascade

  • 如果关联实体未被跟踪,主实体的状态标记为删除,执行SaveChage时,在删除主表的数据的同时,通过数据库的行为删除关联表的数据行;

  • 如果关联实体已经被跟踪,将主实体的状态标记为删除时,关联实体的状态也会标记为删除,执行SaveChange时,先删除关联表的数据行,然后再删除主表的数据行;

  • 外键可以设置非空值、也可以设置为可为空值;

  • 关联实体可以不被跟踪。

DeleteBehavior.SetNull

  • 如果关联实体未被跟踪,主实体的状态标记为删除,执行SaveChage时,在删除主表的数据时,通过数据库的行为将关联表数据行的外键更新为NULL,;

  • 如果关联实体已经被跟踪,将主实体的状态标记为删除时,关联实体的外键会被设置为null,同时将关联实体的状态标记为修改,执行SaveChange时,先更新关联表的数据行 ,然后删除主表的数据行;

  • 因为要将外键更新为NULL,所以外键必须设置为可空字段;

  • 关联实体可以不被跟踪。

DeleteBehavior.ClientSetNull

  • 数据库不会执行任何行为;

  • 关联实体必须被跟踪,将主实体的状态标记为删除时,关联实体的外键被设置为null,同时将关联实体的状态标记为修改,执行SaveChange时,先更新关联表的数据行,然后删除主表的数据行(此时的行为与DeleteBehavior.SetNull一致);

  • 因为要将外键更新为NULL,所以外键必须设置为可空字段;

  • 关联实体必须被跟踪,否则保存数据时会抛出异常。

DeleteBehavior.Restrict

  • 框架不执行任何操作,由开发人员决定关联实体的行为,可以将关联实体的状态设置为删除,也可以将关联实体的外键设置为null;

  • 因为要修改关联实体的状态或外键的值,所以关联实体必须被跟踪。

关于如何进行Entity Framework Core关联删除就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: 如何进行Entity Framework Core关联删除

本文链接: https://www.lsjlt.com/news/303108.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何进行Entity Framework Core关联删除
    这篇文章将为大家详细讲解有关如何进行Entity Framework Core关联删除,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。关联删除通常是一个数据库术语,用于描述...
    99+
    2023-06-22
  • Entity Framework Core关联删除
    目录数据库关联删除行为定义实体Fluent API 配置关联实体创建表结构EF Core 关联实体删除行为总结DeleteBehavior.CascadeDeleteBehavior...
    99+
    2022-11-12
  • 如何对Entity Framework Core进行单元测试
    这篇文章主要介绍如何对Entity Framework Core进行单元测试,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、引言我们先来讲解如何对EntityFrameworkCore进行单元测...
    99+
    2023-06-29
  • MySQL如何删除多表关联
    这篇文章主要介绍MySQL如何删除多表关联,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完! 在MySQL中,删除关联的多张表,可以使用下面SQLmysql&...
    99+
    2022-10-18
  • PHP如何删除关联数组中键值
    1、使用unset()函数可以用于取消设置关联数组中的键及其值。 // 声明关联数组 $arr = array( "1" => "加", "2" =>...
    99+
    2022-11-12
  • mysql如何删除数据表和关联的数据表删除详情
    目录前言一、mysql删除没有被关联的表二、删除被其他表关联的主表前言 删除数据表的时候,表的定义和表中所有的数据均会被删除。因此,在进行删除操作前,最好对表中的数据做一个备份,以免造成无法挽回的后果。 mysql删除数...
    99+
    2022-07-26
    mysql删除数据表 mysql关联数据表删除
  • mysql如何关联更新删除不走索引优化
    这篇文章给大家分享的是有关mysql如何关联更新删除不走索引优化的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。关于update in不走索引的:首先select子查询形...
    99+
    2022-10-18
  • 如何进行GitHub提交删除
    GitHub是一个非常受欢迎的开源社区,它提供了一个方便的平台来存储、管理和分享程序代码。尽管GitHub极其便捷,但是有时我们可能需要从GitHub上删除一些文件或仓库。在这篇文章中,我们将会讨论如何进行GitHub提交删除。首先,让我们...
    99+
    2023-10-22
  • thinkphp5如何进行删除操作
    本篇内容介绍了“thinkphp5如何进行删除操作”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!首先,我们需要了解ThinkPHP5的基本目...
    99+
    2023-07-05
  • Servlet如何进行批量删除
    这篇文章主要介绍了Servlet如何进行批量删除,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Mapper文件in为点选条件 collection为集合 点选id 以“(”开...
    99+
    2023-06-02
  • MySQL如何进行表之间的关联更新
    在实际编程工作或运维实践中,对MySQL数据库表进行关联更新是一种比较常见的应用场景,比如在电商系统中,订单表里保存了商品名称的信息(冗余字段设计),但如果商品名称发生变化,则需要通过关联商品id,把新的商品名称更新到订单表中;或者,学...
    99+
    2023-09-21
    mysql 数据库
  • 如何进行Oracle中update和select 关联操作
    这期内容当中小编将会给大家带来有关如何进行Oracle中update和select 关联操作,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1、介绍本文主要向大家介绍了Oracle数据库...
    99+
    2023-06-26
  • php如何对链接进行删除或修改
    这篇文章主要介绍“php如何对链接进行删除或修改”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“php如何对链接进行删除或修改”文章能帮助大家解决问题。PHP删除链接当我们需要从数据库或其它存储设备中...
    99+
    2023-07-05
  • php如何操作数据库进行模糊删除
    本篇内容主要讲解“php如何操作数据库进行模糊删除”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“php如何操作数据库进行模糊删除”吧!连接数据库在进行数据库操作之前,需要先连接数据库。可以使用 ...
    99+
    2023-07-05
  • thinkphp关联查询如何使用条件进行筛选
    这篇“thinkphp关联查询如何使用条件进行筛选”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“thinkphp关联查询如何...
    99+
    2023-07-05
  • LINQ to SQL是如何怎样进行删除数据的
    LINQ to SQL是如何怎样进行删除数据的,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。我们在学习了LINQ to SQL之查询以及添加和更新的实现之后,现在我们来看看...
    99+
    2023-06-17
  • Linux中如何进行用户的创建修改删除
    这篇文章的内容主要围绕Linux中如何进行用户的创建修改删除进行讲述,文章内容清晰易懂,条理清晰,非常适合新手学习,值得大家去阅读。感兴趣的朋友可以跟随小编一起阅读吧。希望大家通过这篇文章有所收获!大家都知道Linux系统是一个多任务、多用...
    99+
    2023-06-28
  • 如何进行Django中关联查询set.all() 方法的使用
    本篇文章给大家分享的是有关如何进行Django中关联查询set.all() 方法的使用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。比如说有a b c三张表关系如下 a是b的父...
    99+
    2023-06-04
  • 如何在Android项目中使用ViewPager对radiogroup进行关联
    如何在Android项目中使用ViewPager对radiogroup进行关联?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。Android ViewPager与radiog...
    99+
    2023-05-31
    android viewpager radiogroup
  • 微信小程序中如何进行删除处理操作
    这篇文章主要介绍微信小程序中如何进行删除处理操作,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!没有 confrim 那怎么实现这个效果呢?可以使用小程序里的模态框 代码:wxml:&...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作