首页 > 作文

Entity Framework Core关联删除

更新时间:2023-04-04 08:36:35 阅读: 评论:0

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

数据库关联删除行为

我们先来看一看sql rver中支持的行为。在创建外键约束时,可以指定关联表在主表删除行时,对依赖的数据如何执行操作。例如下面的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 t null);

外键约束[fk_order details_orders_orderid]末尾的语句是on delete t中考食谱 null,表示当主表的数据行删除时,自动将关联表数据行的外键更新为null。

在sql rver中支持如下四种行为:

1.on delete no action

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

delete 语句与 reference 约束”fk_order details_orders_orderid”冲突。该冲突发生于数据库”northwind_test”,表”dbo.order details”, column ‘orderid’。

语句已终止。

2.on delete cascade

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

3.on delete t null

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

4.on delete t default

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

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

定义实体

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

    public class order    {        public int orderid { get; t; }        public string name { get; t; }        public datetime? orderdate { get; t; }        public icollection<orderdetail> orderdetails { get; t; }    }    public class orderdetail    {        public int detailid { get; t; }        public int? orderid { get; t; }                public int productid { get; t; }        public order order { get; t; }    }

fluent api 配置关联实体

在dbcontext中onmodelcreating方法中,我们使用 fluent api 配置实体中之间的关系。

    public class northwindcontext : dbcontext    {        public virtual dbt<order> orders { get; t; }        public virtual dbt<orderdetail> orderdetails {建德苞茶 get; t; }        protected override void onmodelcreating(modelbuilder modelbuilder)        {            modelbuilder.entity<o天津高考试卷rder>(                builder =>                {                    builder.hasmany<orderdetail>(e => e.orderdetails).withone(e => e.order).hasforeignkey(e => e.orderid).ondelete(deletebehavior.clienttnull);                });        }    }

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

    public enum deletebehavior    {        cascade,        tnull,        clienttnull,        restrict    }    

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

创建表结构

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

        [inlinedata(deletebehavior.cascade)]        [inlinedata(deletebehavior.tnull)]         [inlinedata(deletebehavior.clienttnull)]        [inlinedata(deletebehavior.restrict)]        [theory]        public void create_databa(deletebehavior behavior)        {            using (var northwindcontext = new northwindcontext(behavior))            {                northwindcontext.databa.ensuredeleted();                northwindcontext.databa.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语句如下:

ef core 关联实体删除行为

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

        [inlinedata(deletebehavior.cascade, true)]        [inlinedata(deletebehavior.cascade, fal)]        [inlinedata(deletebehavior.tnull, true)]        [inlinedata(deletebehavior.tnull, fal)]        [inlinedata(deletebehavior.clienttnull, true)]        [inlinedata(deletebehavior.clienttnull, fal)]        [inlinedata(deletebehavior.restrict, true)]        [inlinedata(deletebehavior.restrict, fal)]        [theory]        public void execute(deletebehavior behavior, bool includedetail)        {            using (var northwindcontext = new northwindcontext(behavior))            {                northwindcontext.databa.ensuredeleted();                northwindcontext.databa.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.t<order>().add(order);                                northwindcontext.savechanges();                orderid = order.orderid;                detailid = orderdetail.detailid;            }            using (var northwindcontext = new northwindcontext(behavior))            {                var queryable = northwindcontext.t<order>().where(e => e.orderid == orderid);                if (includedetail){                    queryable = queryable.include(e => e.orderdetails);                }                var order = queryable.single();                 northwindcontext.t<order>().remove(order);                try                {                    northwindcontext.savechanges();                    dumpsql();                }                catch (exception)                {                    dumpsql();           match是什么意思         throw;                }            }            using (var northwindcontext = new northwindcontext(behavior))            {                var orderdetail = northwindcontext.t<orderdetail>().find(detailid);                if (behavior == deletebehavior.cascade)                {                    asrt.null(orderdetail);                }                el                {                    asrt.notnull(orderdetail);                }            }        }        

总结

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

deletebehavior.cascade

如果关联实体未被跟踪,主实体的状态标记为删除,执行savechage时,在删除主表的数据的同时,通过数据库的行为删除关联表的数据行;如果关联实体已经被跟踪,将主实体的状态标记为删除时,关联实体的状态也会标记为删除,执行savechange时,先删除关联表的数据行,然后再删除主表的数据行;外键可以设置非空值、也可以设置为可为空值;关联实体可以不被跟踪。

deletebehavior.tnull

如果关联实体未被跟踪,主实体的状态标记为删除,执行savechage时,在删除主表的数据时,通过数据库的行为将关联表数据行的外键更新为null,;如果关联实体已经被跟踪,将主实体的状态标记为删除时,关联实体的外键会被设置为null,同时将关联实体的状态标记为修改,执行savechange时,先更新关联表的数据行 ,然后删除主表的数据行;因为要将外键更新为null,所以外键必须设置为可空字段;关联实体可以不被跟踪。

deletebehavior.clienttnull

数据库不会执行任何行为;关联实体必须被跟踪,将主实体的状态标记为删除时,关联实体的外键被设置为null,同时将关联实体的状态标记为修改,执行savechange时,先更新关联表的数据行,然后删除主表的数据行(此时的行为与deletebehavior.tnull一致);因为要将外键更新为null,所以外键必须设置为可空字段;关联实体必须被跟踪,否则保存数据时会抛出异常。

deletebehavior.restrict

框架不执行任何操作,由开发人员决定关联实体的行为,可以将关联实体的状态设置为删除,也可以将关联实体的外键设置为null;因为要修改关联实体的状态或外键的值,所以关联实体必须被跟踪。

以上就是entity framework core关联删除的详细内容,更多关于entity framework关联删除的资料请关注www.887551.com其它相关文章!

本文发布于:2023-04-04 08:36:33,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/zuowen/3c19a0b3ffb6ab7cb9820ebb89c017f4.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

本文word下载地址:Entity Framework Core关联删除.doc

本文 PDF 下载地址:Entity Framework Core关联删除.pdf

标签:实体   数据   状态   语句
相关文章
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图