博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Lind.DDD.ILogicDeleteBehavor~逻辑删除的实现
阅读量:6306 次
发布时间:2019-06-22

本文共 3914 字,大约阅读时间需要 13 分钟。

关于逻辑删除

对于逻辑删除之前的做法是在实体类中加个字段,一般是status,其中一种状态是删除,当然也有其它做法,如加个bool的字段IsDeleted,这些其实都过于武断,即它在基类里加上后,所以实体类都会有这种特性,而对于现实的数据表,可能不显示这种逻辑删除的特性,如关系表,日志表,可能删除就是物理上的直接delete,而这种删除字段加上去,我们的做也是在业务层手动调用update方法,或者在底层提供一个delete方法的重载,总之,感觉不是很爽!

看了ABP的软删除之后,对大叔有了新的启发,即提出一个逻辑删除的接口,所以需要这个字段的实体都去实现这个接口即可!

逻辑删除的接口(对实体属性的装饰)

  ///     /// 具有逻辑删除的接口,实体需要实现这个接口,将IsDeleted实现    /// 在仓储实现类中,delete方法判断实体是否实现了ILogicDeleteBehavor这个接口,然后再决定是否逻辑删除    ///     public interface ILogicDeleteBehavor    {        ///         /// 是否已经删除,默认为false        ///         bool IsDeleted { get; set; }    }

这个接口很干净,只有一个属性,这个属性用来标识删除的状态,true表示已经删除,在进行select操作时我们需要将这个状态过滤,在delete方法里,我们也可以通过判断当前实体是否属于ILogicDeleteBehavor接口而对它采取是否进行逻辑删除!

实体多继承一个接口,完成某个特定的功能

public partial class WebManageUsers :        Lind.DDD.Domain.Entity,        ILogicDeleteBehavor,        IStatusBehavor    {        #region IStatusBehavor 成员        public Status DataStatus { get; set; }        #endregion        #region ILogicDeleteBehavor 成员        public bool IsDeleted { get; set; }        #endregion        public WebManageUsers()        {            this.WebManageRoles = new HashSet
(); this.WebDepartments = new HashSet
(); } [DisplayName("登陆名"), Required] public string LoginName { get; set; } [DisplayName("密码"), Required] public string Password { get; set; } [DisplayName("真实姓名"), Required] public string RealName { get; set; } [DisplayName("手机")] public string Mobile { get; set; } [DisplayName("电子邮件")] public string Email { get; set; } [DisplayName("描述")] public string Description { get; set; } [DisplayName("操作者")] public string Operator { get; set; } [DisplayName("所属项目")] public Nullable
WebSystemID { get; set; } public virtual ICollection
WebManageRoles { get; set; } public virtual ICollection
WebDepartments { get; set; } }

本例采用的是EF的CodeFirst方式,所以需要将自己定义实体,然后根据实体自动生成数据库.

删除方法直接判断实体是否实现了某个接口

public void Delete(TEntity item)        {            if (item != null)            {                if (item is ILogicDeleteBehavor)                {                    //逻辑删除                    var pkList = GetPrimaryKey().Select(i => i.Name);                    var entityType = typeof(TEntity);                    List primaryArr = new List();                    foreach (var primaryField in pkList)                    {                        primaryArr.Add(entityType.GetProperty(primaryField).GetValue(item, null));                    }                    var old = this.Find(primaryArr.ToArray());                    (old as ILogicDeleteBehavor).IsDeleted = true;                    this.Update(old);                }                else                {                    //物理删除                    Db.Set
().Attach(item as TEntity); Db.Entry(item).State = EntityState.Deleted; Db.Set
().Remove(item as TEntity); this.SaveChanges(); } } }

上面的设置,对于在列表里删除某个对象已经可以实现了,而如何去过滤列表里的记录呢,当然直接在DbSet<TEntity>()里去过滤是最好的,但没有直接的方式,因为我们的IsDeleted属性没有对外暴露,而对于Linq to Entity来说,你无法在查询表达式中输

入EDM之外的元素名(那也不认,它只认实体类型),还好在ABP里我找到了不错的方法,就是在数据上下文的OnModelCreating方法上,添加过滤器,这个过滤器需要我们安装EntityFramework.DynamicFilters包,直接用Nuget可以安装.

ModelBuilder.Filter完成对集合的全局过滤

protected override void OnModelCreating(DbModelBuilder modelBuilder)   {            base.OnModelCreating(modelBuilder);            modelBuilder.Filter("LogicDelete", (Lind.DDD.Domain.ILogicDeleteBehavor d) => d.IsDeleted, false);   }

这样在所有Linq Select语句之前都会添加d.IsDeleted==false这个参数完成逻辑删除的过滤功能!

是不是很爽,很酷!

对于实体中其它的比较有特点的属性,而又不是全局的属性,我们都可以使用接口的方式进行定义,这类似于装饰模式,即将某个属性装饰成某个接口,而在程序的另一端直接去操作这个接口即可

本文转自博客园张占岭(仓储大叔)的博客,原文链接:,如需转载请自行联系原博主。

你可能感兴趣的文章
Richard M. Stallman 给《自由开源软件本地化》写的前言
查看>>
oracle数据库密码过期报错
查看>>
修改mysql数据库的默认编码方式 .
查看>>
zip
查看>>
How to recover from root.sh on 11.2 Grid Infrastructure Failed
查看>>
rhel6下安装配置Squid过程
查看>>
《树莓派开发实战(第2版)》——1.1 选择树莓派型号
查看>>
在 Linux 下使用 fdisk 扩展分区容量
查看>>
结合AlphaGo算法和大数据的量化基本面分析法探讨
查看>>
如何在 Ubuntu Linux 16.04 LTS 中使用多个连接加速 apt-get/apt
查看>>
《OpenACC并行编程实战》—— 导读
查看>>
机器学习:用初等数学解读逻辑回归
查看>>
如何在 Ubuntu 中管理和使用逻辑卷管理 LVM
查看>>
Oracle原厂老兵:从负面案例看Hint的最佳使用方式
查看>>
把自己Github上的代码添加Cocoapods支持
查看>>
C语言OJ项目参考(2493)四则运算
查看>>
零基础入门深度学习(二):神经网络和反向传播算法
查看>>
find和xargs
查看>>
数据结构例程—— 交换排序之快速排序
查看>>
WKWebView代理方法解析
查看>>