1、引言数据库
所谓级联删除是指删除一条记录后,附带关联记录也一块儿删除,好比删除客户后,联系人也一块儿删除;设计模式
以往咱们会依赖于数据库表的外键约束,但存在着明显的问题,增长数据库压力、提示不友好、职责越界、事务冲突等,这类业务相关的功能不该该放到数据库去管理。ui
2、依赖注入spa
DI、IOC等概念在这不展开介绍,你们记住它们的主要目的就是解耦,本文利用.netcore内置的DI实现相关功能.net
2、解决方案设计
利用DI注入级联删除的服务,在主体删除时获取已注册的级联删除服务,实现记录的级联删除,前面这句话可能绕口,下面用一个例子说明,删除【实体元数据】时同时删除【字段元数据】,看下代码就清晰了:code
级联删除接口类 ICascadeDeleteblog
1 public interface ICascadeDelete<TParent> 2 { 3 void CascadeDelete(params TParent[] parent); 4 }
字段删除类 AttributeDeleter,实现上面的接口接口
1 public class AttributeDeleter : ICascadeDelete<Domain.Entity> 2 { 3 private readonly IAttributeRepository _attributeRepository; 4 public AttributeDeleter(IAttributeRepository attributeRepository) 5 { 6 _attributeRepository = attributeRepository; 7 } 8 9 /// <summary> 10 /// 实体级联删除 11 /// </summary> 12 /// <param name="parent">被删除的实体</param> 13 public void CascadeDelete(params Domain.Entity[] parent) 14 { 15 //删除字段 16 _attributeRepository.DeleteMany(x =>x.EntityId.In(parent.Select(x => x.EntityId).ToArray())); 17 } 18 }
实体删除类EntityDeleter事务
1 public class EntityDeleter 2 { 3 private readonly IEntityRepository _entityRepository; 4 private readonly IEnumerable<ICascadeDelete<Domain.Entity>> _cascadeDeletes;//须要同时删除记录的服务类 5 public EntityDeleter(IEntityRepository entityRepository 6 , IEnumerable<ICascadeDelete<Domain.Entity>> cascadeDeletes 7 ) 8 { 9 _entityRepository = entityRepository; 10 _cascadeDeletes = cascadeDeletes; 11 } 12 13 14 public bool DeleteById(Guid id) 15 { 16 //执行级联删除,通常放在主记录删除前 17 _cascadeDeletes?.ToList().ForEach((x) => { x.CascadeDelete(deleted); }); 18 //删除实体 19 _entityRepository.DeleteById(id); 20 } 21 }
注册服务
services.AddScoped(typeof(Core.Data.ICascadeDelete<>), typeof(Core.Data.ICascadeDelete<Domain.Entity>));
上面的服务注册方式是固定的写法,但实际项目可能有不少这类同一接口的实现,咱们能够写个批量注册的类去解决,后面再介绍,你们也能够本身查看源码
3、结语
整个过程很简单,但解决了系统设计的几个大问题,包括你们从个人类命名(EntityDeleter)就能够看出,这是职责单一的设计思想,xms应用了不少设计模式,往后会在这里一一分享,这些模式带来的巨大好处