FreeSql AOP 已有的功能介绍, 未来为会根据用户需求不断增强.
审计 CRUD
马云说过, 996 是修福报. 对于多数程序员来说, 加班是好事... 起码不是闲人, 不会下岗.
当如果因为某个 sql 骚操作耗时很高, 没有一个相关的审计功能, 排查起来可以说无从下手, 福报与你紧紧相随 (哈哈).
FreeSql 支持简单的类似功能:
- fsql.Aop.CurdAfter = (s, e) => {
- if (e.ElapsedMilliseconds> 200) {
- // 记录日志
- // 发送短信给负责人
- }
- };
是的, 只需要一个事件, 就可以对全局起到作用.
除了 CurdAfter, 还有一个 CurdBefore (在执行 sql 之前触发).
审计属性值
实现插入 / 更新时统一处理某些值, 比如某属性的雪花算法值, 创建时间值, 甚至是业务值.
- fsql.Aop.AuditValue += (s, e) => {
- if (e.Column.CsType == typeof(long)
- && e.Property.GetCustomAttribute<SnowflakeAttribute>(false) != null
- && e.Value?.ToString() == 0)
- e.Value = new Snowflake().GetId();
- };
- class Order {
- [Snowflake]
- public long Id { get; set; }
- //...
- }
当属性的类型是 long, 并且标记了 [Snowflake], 并且当前值是 0, 那么在插入 / 更新时它的值将设置为雪花 id 值.
说明: SnowflakeAttribute 是使用者您来定义, new Snowflake().GetId() 也是由使用者您来实现
如果命名规范, 可以在 aop 里判断, if (e.Property.Name == "createtime") e.Value = DateTime.Now;
审计迁移脚本
FreeSql 自带迁移功能, 那么迁移的 SQL 语句长啥样, 你可能会好奇.
比如创建表时;
比如添加字段时;
比如修改表名, 修改字段名时;
又比如字段类型更改之后时;
这些操作在 FreeSql.CodeFirst 实现下基本不需要理会, 而且我们只推荐在开发环境使用自动迁移的功能, 正式环境可使用其他工具替代此操作.
但我们仍然可能需要对项目做完整的日志记录.
fsql.Aop.SyncStructureBefore,fsql.Aop.SyncStructureAfter 这两个事件将排上用场.
自定义实体特性
比如项目内已经使用了其它 ORM, 如 efcore, 这样意味着实体中可能存在 [Key], 但它与 FreeSql [Column(IsPrimary = true] 不同.
Q: FreeSql 实体特性为啥这么别扭?
A: 为了考虑一致性用法, 全部封装在 ColumnAttribute 下, 这样用户使用起来, 不用到处 using 或者 回忆特性应该用哪个名字, 如自增 [Column(IsIdentity = true)] 即可.
FreeSql 提供 AOP 自定义特性功能, 实现与多个 ORM 共同拥有一套实体特性, 可避免重复定义特性.
- fsql.Aop.ConfigEntity = (s, e) => {
- var attr = e.EntityType.GetCustomAttributes(
- typeof(System.ComponentModel.DataAnnotations.Schema.TableAttribute), false).FirstOrDefault()
- as System.ComponentModel.DataAnnotations.Schema.TableAttribute;
- if (attr != null)
- e.ModifyResult.Name = attr.Name; // 表名
- };
- fsql.Aop.ConfigEntityProperty = (s, e) => {
- if (e.Property.GetCustomAttributes(
- typeof(System.ComponentModel.DataAnnotations.KeyAttribute), false).Any())
- e.ModifyResult.IsPrimary = true; // 主键
- };
就这样, FreeSql 的实体特性就可以和 EFCore 那样设定了. 其他自增, 乐观锁等, 依葫芦画瓢便是.
自定义表达式
FreeSql 内部表达式支持非常丰富, 对各大数据库的兼容度也做得很好.
有关表达式支持到的程度, 可点击查看详细 wiki:
即便如此丰富, 也仍然无法满足用户需求, FreeSql 对外开放了自定义表达式解析接口:
- fsql.Aop.ParseExpression = (s, e) => {
- if (e.Expression.NodeType == Call && e.Expression.Name == "get_Item")
- e.Result = "1111";
- };
这个解析有点复杂, 当 e.Expression 很复杂的时候, 我们还提供了 e.FreeParse 方法, 使用它相当于调用 FreeSql 内置表达式解析引擎, 辅助您进行解析.
Aop.Where
FreeSql 提供的 ISelect,IDelete,IUpdate 三大对象, 都可以使用 .Where(lambda) 操作, 也可以是 .Where(sql) 操作.
Aop.Where 的定位是可拦截 Where 条件.
- fsql.Aop.Where = (s, e) => {
- if (e.Parameter[0]?.ToString() == "1")
- e.IsCancel = true;
- };
- Aop.ToList
监控 ToList 返回的的数据, 用于拦截重新装饰.
所有通过 FreeSql.Select 查询返回的时候, 都可以在这个事件上进行重新装饰.
系列文章导航
(一) 入门 https://www.cnblogs.com/FreeSql/p/11531300.html
(二) 自动迁移实体 https://www.cnblogs.com/FreeSql/p/11531301.html
(三) 实体特性 https://www.cnblogs.com/FreeSql/p/11531302.html
(四) 实体特性 Fluent API https://www.cnblogs.com/FreeSql/p/11531304.html
(五) 插入数据 https://www.cnblogs.com/FreeSql/p/11531306.html
(六) 批量插入数据 https://www.cnblogs.com/FreeSql/p/11531309.html
(七) 插入数据时忽略列 https://www.cnblogs.com/FreeSql/p/11531316.html
(八) 插入数据时指定列 https://www.cnblogs.com/FreeSql/p/11531318.html
(九) 删除数据 https://www.cnblogs.com/FreeSql/p/11531320.html
(十) 更新数据 https://www.cnblogs.com/FreeSql/p/11531321.html
(十一) 更新数据 Where https://www.cnblogs.com/FreeSql/p/11531324.html
(十二) 更新数据时指定列 https://www.cnblogs.com/FreeSql/p/11531327.html
(十三) 更新数据时忽略列 https://www.cnblogs.com/FreeSql/p/11531334.html
(十四) 批量更新数据 https://www.cnblogs.com/FreeSql/p/11531335.html
(十五) 查询数据 https://www.cnblogs.com/FreeSql/p/11531339.html
(十六) 分页查询 https://www.cnblogs.com/FreeSql/p/11531341.html
(十七) 联表查询 https://www.cnblogs.com/FreeSql/p/11531346.html
(十八) 导航属性 https://www.cnblogs.com/FreeSql/p/11531352.html
(十九) 多表查询 https://www.cnblogs.com/FreeSql/p/11531362.html
(二十) 多表查询 WhereCascade https://www.cnblogs.com/FreeSql/p/11531372.html
(二十一) 查询返回数据 https://www.cnblogs.com/FreeSql/p/11531376.html
(二十二)Dto 映射查询 https://www.cnblogs.com/FreeSql/p/11531381.html
(二十三) 分组, 聚合 https://www.cnblogs.com/FreeSql/p/11531384.html
(二十四)Linq To Sql 语法使用介绍 https://www.cnblogs.com/FreeSql/p/11531392.html
(二十五) 延时加载 https://www.cnblogs.com/FreeSql/p/11531395.html
(二十六) 贪婪加载 Include,IncludeMany,Dto,ToList https://www.cnblogs.com/FreeSql/p/11531404.html
(二十七) 将已写好的 SQL 语句, 与实体类映射进行二次查询 https://www.cnblogs.com/FreeSql/p/11531416.html
(二十八) 事务 https://www.cnblogs.com/FreeSql/p/11531423.html
(二十九)Lambda 表达式 https://www.cnblogs.com/FreeSql/p/11531425.html
(三十) 读写分离 https://www.cnblogs.com/FreeSql/p/11531430.html
(三十一) 分区分表 https://www.cnblogs.com/FreeSql/p/11531435.html
(三十二)Aop
(三十三)CodeFirst 类型映射 https://www.cnblogs.com/FreeSql/p/11531543.html
(三十四)CodeFirst 迁移说明 https://www.cnblogs.com/FreeSql/p/11531550.html
(三十五)CodeFirst 自定义特性 https://www.cnblogs.com/FreeSql/p/11531576.html
来源: http://www.bubuko.com/infodetail-3201559.html