EF Core 5.0 使用過濾器進行查詢攔截的方法和示例,以及一些備忘
阿新 • • 發佈:2021-09-07
1、查詢攔截和結果替換(取消執行)的示例:
/// <summary> /// 查詢攔截器 /// </summary> public class ShardingDbCommandInterceptor : Microsoft.EntityFrameworkCore.Diagnostics.DbCommandInterceptor { /// <summary> /// 在這裡做攔截、判斷、取消查詢、賦值操作 /// </summary> /// <param name="command"></param> /// <param name="eventData"></param> /// <param name="result"></param> /// <returns></returns> public override InterceptionResult<DbDataReader> ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult<DbDataReader> result) { Console.WriteLine(command.CommandText); //取引數列表 foreach (System.Data.Common.DbParameter p in command.Parameters) { Console.WriteLine($" 引數名:{p.ParameterName},引數值:{p.Value},引數方向:{p.Direction}"); } Console.WriteLine($"當前資料庫名稱:{command.Connection.Database},資料來源為:{command.Connection.DataSource},伺服器版本:{command.Connection.ServerVersion}"); //定義一個Table,如果執行下面的程式碼,即攔截成功,自動被取消執行 var dt = new System.Data.DataTable(); dt.Columns.Add("Id", typeof(string)); dt.Columns.Add("AccountId", typeof(Int64)); var rs = dt.NewRow(); rs["Id"] = Guid.NewGuid().ToString(); rs["AccountId"] = 1234; dt.Rows.Add(rs); result = InterceptionResult<DbDataReader>.SuppressWithResult(dt.CreateDataReader()); return result; } /// <summary> /// 執行完畢後會返回 /// </summary> /// <param name="command"></param> /// <param name="eventData"></param> /// <param name="result"></param> /// <returns></returns> public override DbDataReader ReaderExecuted(DbCommand command, CommandExecutedEventData eventData, DbDataReader result) { return base.ReaderExecuted(command, eventData, result); } }
2、註冊過濾器的程式碼:
/// <summary> /// 多庫、分庫、分表、Redis自動化 上下文物件 /// </summary> public class DataContexts:DbContext { public DataContexts() : base() { } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("Data Source=192.168.3.162;Initial Catalog=hmt_report;Persist Security Info=True;User ID=sa;Password=123").AddInterceptors(new ShardingDbCommandInterceptor()); } /// <summary> /// 重寫該方法,用於實現批量生成SQL進行批量操作,例如批量插入,以及做Redis的更新 /// </summary> /// <returns></returns> public override int SaveChanges() { return base.SaveChanges(); } /// <summary> /// 聲明當前資料庫上下文使用的全部模型和反射欄位列表 /// </summary> public static Dictionary<string, System.Reflection.PropertyInfo[]> modelProperties { get; set; } = new Dictionary<string, System.Reflection.PropertyInfo[]>(); /// <summary> /// 表 AudienceAccountReport_DataOnDay /// </summary> public DbSet<ShardingEntityFramework.DataModels.AudienceAccountReport_DataOnDay> AudienceAccountReport_DataOnDay { get; set; } }
EF Framework也是一樣,有了該攔截器後,可以擴充套件為Redis自動化,只要識別出來查詢語句中的目標表,以及鍵欄位有具體值,就可以直接從redis裡取,然後,讀寫分離也是基於攔截器來改變資料庫連線字串,就可以實現讀寫的分離,另外,要自動更新redis或者讀寫分離,則通過覆蓋重寫
SaveChanges 函式來實現,同時,分庫分表也涉及到這個地方,實際上,特別是分表稍為麻煩一些,分表因為有多種不同規則,分表方法,核心難點是解析SQL裡的條件,得出表名和對不同表的where欄位及值,進行做實際表的替換,來實現自動化分表哦。
僅僅是思路。