zoukankan      html  css  js  c++  java
  • FreeSql 已支持 .NetFramework 4.0、ODBC 访问

    FreeSql 开源发布快一年了,目前主仓库代码量 64118 行,用 git 命令统计的命令如下:

    find . "(" -name "*.cs" ")" -print | xargs wc -l

    加上其他几个扩展包的代码,大约有 70000 行源码。

    仓库地址:https://github.com/2881099/FreeSql

    在金九银十的日子,发布了两大重要支持更新,分别是 .NetFramework4.0 和 ODBC。

    随着不断的迭代更新,越来越稳定,也越来越强大。预计在一周年的时候(2020年1月1日)发布 1.0 正式版本。

    由于篇幅原因,太短则上不了首页,同时也对不起观众,下面介绍一下最近更新的几个较实用的功能:

    ISelect.ToDelete/ToUpdate

    IFreeSql 之 CRUD 方法,分别对应 IInsert、ISelect、IUpdate、IDelete。

    IDelete 默认不支持导航对象,多表关联等。ISelect.ToDelete 可将查询对象转为删除对象,以便支持导航对象或其他查询功能删除数据,如下:

    fsql.Select<T1>().Where(a => a.Options.xxx == 1).ToDelete().ExecuteAffrows();
    

    注意:此方法不是将数据查询到内存循环删除,上面的代码产生如下 SQL 执行:

    DELETE FROM `T1` WHERE id in (select a.id from T1 a left join Options b on b.t1id = a.id where b.xxx = 1)
    

    复杂删除使用该方案的好处:

    • 删除前可预览测试数据,防止错误删除操作,实现所查、即所删;
    • 支持更加复杂的删除操作(IDelete 默认只支持简单的操作),甚至在 ISelect 上使用 Limit(10) 将只删除附合条件的前 10条记录;

    ToUpdate 功能大概相同。

    GlobalFilter 全局过滤

    FreeSql 基础层实现了 Select/Update/Delete 可设置的全局过滤器功能。

    public static AsyncLocal<Guid> TenantId { get; set; } = new AsyncLocal<Guid>();
    
    fsql.GlobalFilter
        .Apply<TestAddEnum>("test1", a => a.Id == TenantId.Value)
        .Apply<AuthorTest>("test2", a => a.Id == 111)
        .Apply<AuthorTest>("test3", a => a.Name == "11");
    

    Apply 泛型参数可以设置为任何类型,当使用 Select/Update/Delete 方法时会进行过滤器匹配尝试(try catch):

    • 匹配成功的,将附加 where 条件;
    • 匹配失败的,标记下次不再匹配,避免性能损耗;

    如何禁用?

    fsql.Select<TestAddEnum>().ToList(); //所有生效
    fsql.Select<TestAddEnum>().DisableGlobalFilter("test1").ToList(); //禁用 test1
    fsql.Select<TestAddEnum>().DisableGlobalFilter().ToList(); //禁用所有
    

    fsql.Update/Delete 方法效果同上。

    仓储过滤器(旧功能)

    这是一个原先就支持了的功能。FreeSql.Repository 也同样实现了过滤器功能,它不仅是查询时过滤,连删除/修改/插入时都会进行验证,避免数据安全问题。

    注意:仓储的过滤器与 IFreeSql.GlobalFilter 不是一个功能,可以同时生效

    每个仓储实例都有 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 (repo1.DataFilter.Disable("test")) {
        //在这段中,repo1 之 test 过滤器失效
    }
    
    //repo1 之 test 过滤器重新生效
    

    过滤与验证

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

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

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

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

    实体变化通知

    该功能依附在 FreeSql.Repository 上实现的,对实体的变化进行统一转发,以便实现全局或局部类似日志的功能。

    全局设置:

    fsql.SetDbContextOptions(opt => {
        opt.OnEntityChange = report => {
            Console.WriteLine(report);
        };
    });
    

    单独设置 DbContext 或者 UnitOfWork:

    var ctx = fsql.CreateDbContext();
    ctx.Options.OnEntityChange = report => {
        Console.WriteLine(report);
    };
    
    var uow = fsql.CreateUnitOfWork();
    uow.OnEntityChange = report => {
        Console.WriteLine(report);
    };
    

    参数 report 是一个 List 集合,集合元素的类型定义如下:

    public class EntityChangeInfo
    {
        public object Object { get; set; }
        public EntityChangeType Type { get; set; }
    }
    public enum EntityChangeType { Insert, Update, Delete, SqlRaw }
    
    变化类型- 说明
    Insert 实体对象被插入
    Update 实体对象被更新
    Delete 实体对象被删除
    SqlRaw 执行了SQL语句

    SqlRaw 目前有两处地方比较特殊:

    • 多对多联级更新导航属性的时候,对中间表的全部删除操作;
    • 通用仓储类 BaseRepository 有一个 Delete 方法,参数为表达式,而并非实体;
    int Delete(Expression<Func<TEntity, bool>> predicate);
    

    DbContext.SaveChanges,或者 Repository 对实体的 Insert/Update/Delete,或者 UnitOfWork.Commit 操作都会最多触发一次该事件。

    更多功能

    请移步更新日志:https://github.com/2881099/FreeSql/wiki/更新日志

  • 相关阅读:
    Python随笔——Map之键对应多值的处理
    Python操作cx_Oracle笔记
    jmeter进阶之Beanshell引用Java代码
    碎片记录——JMeter之 http post json对象与参数化调用,以及beanshell 引用Java源码
    java源码生成可运行jar
    小记:web安全测试之——固定session漏洞
    Git关联JIRA的issue
    APP稳定性测试-monkey执行
    maven之assembly插件
    wrapper配置文件详解
  • 原文地址:https://www.cnblogs.com/kellynic/p/11768147.html
Copyright © 2011-2022 走看看