• FreeSql配合仓储实现软删除


    该篇内容由个人博客点击跳转同步更新!转载请注明出处!

    前段时间使用FreeSql作为ORM,写了一个简单的CMS,在这里总结一下其中的使用心得。

    仓储配合全局过滤器

    1. 统一的删除标志

    如:数据库字段 bool IsDeleted,代表删除标志。

    需要配合仓储可实现,统一的删除标志,不需要加where(r=>r.deleted==false),取数据时,自动过滤数据。

    接口 ISoftDeleteAduitEntity.cs

        public interface ISoftDeleteAduitEntity
        {
            bool IsDeleted { get; set; }
            long? DeleteUserId { get; set; }
            DateTime? DeleteTime { get; set; }
        }
    
    

    ConfigureServices通过配置服务,增加全局过滤器,第二个参数,可指定仓储所在的程序集(一个dll,一个项目就是一个程序集(一般一个解决方案下有多个项目,如果仓储写在多个地方,我们可以,把要扫描的程序集写在第二个参数上。))

    services.AddFreeRepository(filter =>
    {
        filter.Apply<ISoftDeleteAduitEntity>("SoftDelete", a => a.IsDeleted == false);
    }, GetType().Assembly, typeof(AuditBaseRepository<>).Assembly);
    

    GetType().Assembly 当前项目所在程序集。
    typeof(AuditBaseRepository<>).Assembly,为AuditBaseRepository所在程序集,(LinCms.Zero.dll)

    2.统一的删除时间,删除人

    上文,关于配置删除标志,我们注入其提供好的仓储,会过滤掉isdeleted属性为true的值。

      public class UserService : IUserSevice
        {
            private readonly BaseRepository<LinUser> _userRepository;
            public UserService(BaseRepository<LinUser> userRepository)
            {
                _userRepository = userRepository;
            }
    
            public List<LinUser> GetUserList()
            {
                List<LinUser> users = _userRepository.Select.ToList();
                return users;
            }
    }
    

    那么,我们删除一个用户时,怎么增加删除时间,删除人呢。

    public void Delete(int id)
    {
        _userRepository.Delete(r => r.Id == id);
    }
    

    这样能删除,但删除人,删除时间并没有加上去。

    这里我们注入AuditBaseRepository,重写父类Delete方法。

    private readonly AuditBaseRepository<LinUser> _userRepository;
    public UserService(AuditBaseRepository<LinUser> userRepository)
    {
        _userRepository = userRepository;
    }
    
    public void Delete(int id)
    {
        _userRepository.Delete(r => r.Id == id);
    }
    
    

    由于父类并非Virtual类型,这里通过new关键字重写 int Delete(Expression<Func<T, bool>> predicate)方法

    public new int Delete(Expression<Func<T, bool>> predicate)
    {
        if (typeof(ISoftDeleteAduitEntity).IsAssignableFrom(typeof(T)))
        {
            List<T> items = Orm.Select<T>().Where(predicate).ToList();
            return Orm.Update<T>(items)
                .Set(a => (a as ISoftDeleteAduitEntity).IsDeleted, true)
                .Set(a => (a as ISoftDeleteAduitEntity).DeleteUserId, _currentUser.Id)
                .Set(a => (a as ISoftDeleteAduitEntity).DeleteTime, DateTime.Now)
                .ExecuteAffrows();
        }
    
        return base.Delete(predicate);
    }
    
    

    全部重写删除操作,请参考https://github.com/luoyunchong/lin-cms-dotnetcore/blob/master/src/LinCms.Zero/Repositories/AuditBaseRepository.cs
    这样固然能实现,但好像包含大量as,IsAssignableFrom(判断T是否继承了ISoftDeleteAduitEntity).

  • 相关阅读:
    K3s+Jetson Nano,在边缘端实现实时视频分析!
    15分钟连接Jetson Nano与K8S,轻松搭建机器学习集群
    配置高可用K3s集群完全攻略
    K3s+Sysdig,8分钟部署并保护集群安全!
    1款工具助力Rancher HA快速部署,极速提升研发测试效率
    连刷40道题,告别动态规划,谈谈我的经验
    直通BAT算法精讲视频教程分享
    关于三次握手和四次挥手,面试官想听到怎样的回答?
    Redisson 分布式锁实战与 watch dog 机制解读
    Spring 注解动态数据源设计实践
  • 原文地址:https://www.cnblogs.com/igeekfan/p/11689624.html
Copyright © 2020-2023  润新知