关联删除通常是一个数据库术语,用于描述在删除行时允许自动触发删除关联行的特征;即当主表的数据行被删除时,自动将关联表中依赖的数据行进行删除,或者将外键更新为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; } }
在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语句如下:
我们分别通过枚举值与是否跟踪关联实体,进行代码测试,测试代码如下:
[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); } } }
根据上面的测试结果,我们可以出得如下结论:
以上就是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 条评论) |