Furion 逻辑删除

本文就当下最流行的dotnet core框架furion中软删除功能的实现进行描述,由于个人水平有限,对Furion研究不是特别深入,如有描述不当请各位看官及时批评指正  


首先我们需要明确使用环境


1. vscode2019
2. dotnet core 5.0+
3. furion 2.18.7
4. 数据库pgsql(这一实现逻辑对数据库依赖不是很敏感)

准备工作  


首先你需要准备好开发环境,并对furion有所了解,在自己的项目中搭建好furion的运行环境,[参考文档](https://dotnetchina.gitee.io/furion/docs)里面的`入门指南`

OK 现在项目环境准备妥当之后,我们开始编写第一个软删除的工具类即软删除字段特性`FakeDeleteAttribute`,本文主要实现的是逻辑删除描述字段为bool型,你可以根据自己的需求进行修改调整,实现代码如下:

  1.  创建软删除特性  `FakeDeleteAttribute`
  2.  创建自定义仓储操作 `PrivateRepository`
  3.  在数据模型中使用 `FakeDelete`
  4.  在数据模型中添加全局过滤 `IEntityTypeBuilder`
  5.  在业务逻辑中进行调用

 1. 创建软删除特性
 

    /// <summary>
    /// 假删除/软删除
    /// </summary>
    [AttributeUsage(AttributeTargets.Property)]
    public class FakeDeleteAttribute : Attribute
    {
        /// <summary>
        /// 构造函数
        ///此处主要用来标识该特性是否启用
        /// </summary>
        /// <param name="state"></param>
        public FakeDeleteAttribute(bool state)
        {
            State = state;
        }

        /// <summary>
        /// 是否启用该特性
        /// </summary>
        public bool State { get; set; }
    }


 

2. 创建自定义仓储操作


2.1 第一种实现方式,该方法灵活性较差,将主键与删除标记字段写死在代码里,不易变通

/// <summary>
/// 软删除工具
/// </summary>
public static class PrivateRepository
{
    private static string PrimaryKeyName { get; set; } = "Id";
    private static string FakeDeleteColumnName { get; set; } = "DeltFlag";
    public static bool FakeDelete<TEntity>(this IWritableRepository<TEntity> repository, long id) where TEntity : class, IPrivateEntity, new()
    {
        TEntity t = System.Activator.CreateInstance<TEntity>();
        t.SetPropertyValue(PrimaryKeyName, id);
        return repository.FakeDelete(t);
    }
    public static bool FakeDelete<TEntity>(this IWritableRepository<TEntity> repository, TEntity entity)
        where TEntity : class, IPrivateEntity, new()
    {
        entity.SetPropertyValue(FakeDeleteColumnName, true); 
        var res=repository.UpdateInclude(entity,new string[] { FakeDeleteColumnName }, true);
        if (EntityState.Modified.Equals(res.State))
            return true;
        return false;
    }
    /// <summary>
    /// 向对象实体通过反射进行属性赋值
    /// </summary>
   private static TEntity SetPropertyValue<TEntity>(this TEntity t, string columnName, object value)
    {
        var targetObj = typeof(TEntity);
        foreach (PropertyInfo sp in targetObj.GetProperties())
        {
            if (sp.Name.Equals(columnName))
            {
                sp.SetValue(t,value);
                return t;
            }
        }
        return t;
    }
}


2.2 第二种实现方式,该方法移除了对字段名称的高度依赖,转为使用数据模型特性识别,要求模型实体主键,必须使用特性`[Key]`,删除标记字段必须使用特性`[FakeDelete]` 
 

    /// <summary>
    /// 软删除工具
    /// </summary>
    public static class PrivateRepository
    {
        private static string FakeDeleteColumnName = null;
        public static bool FakeDelete<TEntity>(this IWritableRepository<TEntity> repository, long id) where TEntity : class, IPrivateEntity, new()
        {
            if (id <= 0)
                return false;
            TEntity t = System.Activator.CreateInstance<TEntity>();
            t.SetPropertyValue(id,true);
            return repository.FakeDelete(t);
        }
        public static bool FakeDelete<TEntity>(this IWritableRepository<TEntity> repository, TEntity entity)
            where TEntity : class, IPrivateEntity, new()
        {
            entity.SetPropertyValue(true,false);
            if (string.IsNullOrEmpty(FakeDeleteColumnName))
                return false;
            var res = repository.UpdateInclude(entity, new string[] { FakeDeleteColumnName }, true);
            if (EntityState.Modified.Equals(res.State))
                return true;
            return false;
        }
        /// <summary>
        /// 向对象实体通过反射进行属性赋值
        /// </summary>
        private static TEntity SetPropertyValue<TEntity>(this TEntity t,object value,bool isKey)
        {
            var targetObj = typeof(TEntity);
            foreach (PropertyInfo sp in targetObj.GetProperties())
            {
                if (sp.IsDefined(typeof(KeyAttribute), true)&&isKey)
                {
                    sp.SetValue(t, value);
                    break;
                }
                else if(sp.IsDefined(typeof(FakeDeleteAttribute), true)&&!isKey)
                {
                    //判断逻辑删除特性是否启用
                    if (((FakeDeleteAttribute)sp.GetCustomAttribute(typeof(FakeDeleteAttribute))).State)
                    {
                        FakeDeleteColumnName = sp.Name;
                        sp.SetValue(t, value);
                        break;
                    }
                }
            }
            return t;
        }  
    }


3. 在数据模型中使用并且添加全局过滤

public class TestEntity:IEntity, IEntityTypeBuilder<TestEntity>
    {
        [Key]
        public long Id { get; set; }
        public string Value { get; set; }
        //使用FakeDelete特性
        [FakeDelete(true),JsonIgnore]
        public string DeleteMark { get; set; }
        //添加全局过滤
        public void Configure(EntityTypeBuilder<TestEntity> entityBuilder, DbContext dbContext, Type dbContextLocator)
        {
            entityBuilder.HasQueryFilter(u => !u.DeltFlag);
        }
    }


4. 在业务逻辑中进行调用

 

       private readonly IWritableRepository<TestEntity> write;
        public TestService(IRepository<TestEntity> testRepository)
        {
            write = personRepository.Constraint<IWritableRepository<AlarmThresholdInfo>>();
        }
         /// <summary>
        /// 逻辑删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [UnitOfWork]
        public bool DeleteLogic(long id)
        {
           return = write.FakeDelete(id);
        }


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值