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:https://github.com/2881099/FreeSql/wiki/%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%87%BD%E6%95%B0
即便如此豐富,也仍然無法滿足用戶需求,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 查詢返回的時候,都可以在這個事件上進行重新裝飾。
系列文章導航
(一)入門
(二)自動遷移實體
(三)實體特性
(四)實體特性 Fluent Api
(五)插入數據
(六)批量插入數據
(七)插入數據時忽略列
(八)插入數據時指定列
(九)刪除數據
(十)更新數據
(十一)更新數據 Where
(十二)更新數據時指定列
(十三)更新數據時忽略列
(十四)批量更新數據
(十五)查詢數據
(十六)分頁查詢
(十七)聯表查詢
(十八)導航屬性
(十九)多表查詢
(二十)多表查詢 WhereCascade
(二十一)查詢返回數據
(二十二)Dto 映射查詢
(二十三)分組、聚合
(二十四)Linq To Sql 語法使用介紹
(二十五)延時加載
(二十六)貪婪加載 Include、IncludeMany、Dto、ToList
(二十七)將已寫好的 SQL 語句,與實體類映射進行二次查詢
(二十八)事務
(二十九)Lambda 表達式
(三十)讀寫分離
(三十一)分區分表
(三十二)Aop
(三十三)CodeFirst 類型映射
(三十四)CodeFirst 遷移說明
(三十五)CodeFirst 自定義特性