zoukankan      html  css  js  c++  java
  • FreeSql 过滤器使用介绍

    FreeSql.Repository 实现了过滤器,它不仅是查询时过滤,连删除/修改/插入时都会进行验证,避免数据安全问题。

    过滤器

    目前过滤器依附在仓储层实现,每个仓储实例都有 IDataFilter 属性,可利用其完成过滤器管理,它是独立的修改后不影响全局。

    public interface IDataFilter<TEntity> where TEntity : class {
        IDataFilter<TEntity> Apply(string filterName, Expression<Func<TEntity, bool>> filterAndValidateExp);
    
        IDisposable Enable(params string[] filterName);
        IDisposable EnableAll();
    
        IDisposable Disable(params string[] filterName);
        IDisposable DisableAll();
    
        bool IsEnabled(string filterName);
    }
    

    临时禁用

    using (repos1.DataFilter.Disable("test")) {
        //在这段中,repos1 之 test 过滤器失效
    }
    
    //repos1 之 test 过滤器重新生效
    

    如何使用仓储

    dotnet add package FreeSql.Repository

    var fsql = new FreeSql.FreeSqlBuilder()
        .UseConnectionString(FreeSql.DataType.Sqlite, @"Data Source=|DataDirectory|document.db;Pooling=true;Max Pool Size=10")
        .UseLogger(loggerFactory.CreateLogger<IFreeSql>())
        .UseAutoSyncStructure(true) //自动迁移实体的结构到数据库
        .Build();
    
    public class Song {
        [Column(IsIdentity = true)]
        public int Id { get; set; }
        public string Title { get; set; }
    }
    

    1、IFreeSql 的扩展方法;

    var curd1 = fsql.GetRepository<Song, int>();
    var curd2 = fsql.GetGuidRepository<Song>();
    

    2、继承现实;

    public class SongRepository : BaseRepository<Song, int> {
        public SongRepository(IFreeSql fsql) : base(fsql) {}
    
        //在这里增加 CURD 以外的方法
    }
    

    3、Autofac 注入,使用方法继续往下看【全局过滤器】;

    过滤与验证

    假设我们有User(用户)、Topic(主题)两个实体,在领域类中定义了两个仓储:

    var userRepository = fsql.GetGuidRepository<User>();
    var topicRepository = fsql.GetGuidRepository<Topic>();
    

    在开发过程中,总是担心 topicRepository 的数据安全问题,即有可能查询或操作到其他用户的主题。因此我们在v0.0.7版本进行了改进,增加了 filter lambad 表达式参数。

    var userRepository = fsql.GetGuidRepository<User>(a => a.Id == 1);
    var topicRepository = fsql.GetGuidRepository<Topic>(a => a.UserId == 1);
    
    • 在查询/修改/删除时附加此条件,从而达到不会修改其他用户的数据;
    • 在添加时,使用表达式验证数据的合法性,若不合法则抛出异常;

    全局过滤器

    全局过滤器,可帮助实现“软删除”、“租户”等设计,目前使用 Autofac 注入的方式实现的全局过滤器。

    public IServiceProvider ConfigureServices(IServiceCollection services) {
        services.AddSingleton<IFreeSql>(fsql);
        services.AddMvc();
    
        var builder = new ContainerBuilder();
    
        //示范全局过滤的仓储类注入,如果实体中不存在 Title 属性,则条件不生效
        builder.RegisterFreeRepository(filter => 
            filter.Apply<Song>("test", a => a.Title == DateTime.Now.ToString() + Thread.CurrentThread.ManagedThreadId)
        );
    
        builder.Populate(services);
        var container = builder.Build();
        return new AutofacServiceProvider(container);
    }
    
    public class xxxx {
        public int Id { get; set; }
    }
    public class Song {
        [Column(IsIdentity = true)]
        public int Id { get; set; }
        public string Title { get; set; }
    }
    //在控制器使用
    public SongsController(GuidRepository<Song> repos1, GuidRepository<xxxx> repos2) {
        //在此打断点,调试
    }
    

    第一次请求:

    repos1.Select.ToSql()

    "SELECT a."Id", a."Title" FROM "Song" a WHERE (a."Title" = strftime('%Y-%m-%d %H:%M.%f',datetime(current_timestamp,'localtime')) || 21)"

    repos2.Select.ToSql()

    "SELECT a."Id" FROM "xxxx" a"

    第二次请求:

    repos1.Select.ToSql()

    "SELECT a."Id", a."Title" FROM "Song" a WHERE (a."Title" = strftime('%Y-%m-%d %H:%M.%f',datetime(current_timestamp,'localtime')) || 4)"

    repos2.Select.ToSql()

    "SELECT a."Id" FROM "xxxx" a"

    //禁用过滤器
    repos1.DataFilter.Disable("test")

    repos1.Select.ToSql()

    "SELECT a."Id", a."Title" FROM "Song" a"

    测试总结:

    1、注入的变量值在使用时有了动态变化,每次获取时都是新的(Thread.CurrentThread.ManagedThreadId);

    2、设定的全局过滤,若某实体不存在表达式函数中的字段时,不会生效(如上xxxx不存在Title);

    3、使用 DataFilter.Disable("test") 可临时关闭过滤器的效果,使用 DataFilter.Enable("test") 可重新开启;

    4、仓储对象创建时,从全局过滤器copy进来,然后自己管理自己。修改后不影响其他或全局设置。

    github 源码: https://github.com/2881099/FreeSql

  • 相关阅读:
    HDU 2888 Check Corners (模板题)【二维RMQ】
    POJ 3264 Balanced Lineup(模板题)【RMQ】
    poj 3368 Frequent values(经典)【RMQ】
    SPOJ RPLN (模板题)(ST算法)【RMQ】
    UVA 796 Critical Links(模板题)(无向图求桥)
    UVA 315 Network (模板题)(无向图求割点)
    POJ 2029 Get Many Persimmon Trees (模板题)【二维树状数组】
    poj 3067 Japan 【树状数组】
    POJ 2481 Cows 【树状数组】
    POJ 1195 Mobile phones【二维树状数组】
  • 原文地址:https://www.cnblogs.com/kellynic/p/10519398.html
Copyright © 2011-2022 走看看