注意:Aop一定要设置在你操作语句之前,不然不会生效,还有必须是同一个SqlSuagrClient才会有效
public SqlSugarClient GetInstance() { SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = "Server=.xxxxx", DbType = DbType.SqlServer, IsAutoCloseConnection = true, InitKeyType = InitKeyType.Attribute }); //每次Sql执行前事件 db.Aop.OnLogExecuting = (sql, pars) => { //我可以在这里面写逻辑 }; return db; } var db=GetInstance(); db.Queryable<T>().ToList();//执行操作会进事件
全部事件
//SQL执行完 db.Aop.OnLogExecuted = (sql, pars) => { //执行完了可以输出SQL执行时间 (OnLogExecutedDelegate) Console.Write("time:" + db.Ado.SqlExecutionTime.ToString()); }; db.Aop.OnLogExecuting = (sql, pars) => //SQL执行前 { //5.0.8.2 获取无参数化 SQL //UtilMethods.GetSqlString(DbType.SqlServer,sql,pars) }; db.Aop.OnError = (exp) =>//SQL报错 { //exp.sql 这样可以拿到错误SQL,性能无影响拿到ORM带参数使用的SQL //5.0.8.2 获取无参数化 SQL 对性能有影响,特别大的SQL参数多的,调试使用 //UtilMethods.GetSqlString(DbType.SqlServer,exp.sql,exp.parameters) }; db.Aop.OnExecutingChangeSql = (sql, pars) => //可以修改SQL和参数的值 { //sql=newsql //foreach(var p in pars) //修改 return new KeyValuePair<string, SugarParameter[]>(sql,pars); };
数据过滤器
插入或者更新可以修改 实体里面的值,比如插入或者更新 赋默认值 (审计)
db.Aop.DataExecuting = (oldValue, entityInfo) => { /*** inset生效 ***/ if (entityInfo.PropertyName == "CreateTime"&&entityInfo.OperationType== DataFilterType.InsertByObject) { entityInfo.SetValue(DateTime.Now);//修改CreateTime字段 //entityInfo有字段所有参数 // oldValue表示当前字段值 等同于下面写法 // var value=entityInfo.EntityColumnInfo.PropertyInfo.GetValue(entityInfo.EntityValue); } //特性用法 //if(p.EntityColumnInfo.PropertyInfo.GetCustomAttribute<自定义特性>()!=null // &&entityInfo.OperationType== DataFilterType.InsertByObject) //5.1.3.23 更好的支持了特性 //p.IsAnyAttribute<特性>() //p.GetAttribute<特性>() /*** update生效 ***/ if (entityInfo.PropertyName =="UpdateTime" && entityInfo.OperationType == DataFilterType.UpdateByObject) { entityInfo.SetValue(DateTime.Now);//修改UpdateTime字段 } //根据当前列修改另一列 可以么写 //if(当前列逻辑==XXX) //var properyDate = entityInfo.EntityValue.GetType().GetProperty("Date"); //if(properyDate!=null) //properyDate.SetValue(entityInfo.EntityValue,1); }; /***实体插入都支持***/ db.Insertable(data).ExecuteReturnIdentity(); /***实体方式更新***/ db.Updateable(data).ExecuteCommand(); db.Updateable(insertObj).IgnoreColumns(ignoreAllNullColumns:true).ExecuteCommand(); /***表达式方式更新***/ //新功能 5.1.3.2:表达式更新支持数据过滤器 db.Updateable<Order>() .SetColumns(it => new Order(){Name="A"} ,appendColumnsByDataFilter:true)//true表式追加过滤器赋值字段 .Where(it=>it.Id==1).ToSqlString() //兼容其它ORM AOP写法 //SqlSugar是通过每行记录每个值进行的细粒度AOP,如果一行数据只想进一次事件 if (entityInfo.EntityColumnInfo.IsPrimarykey) //通过主键保证只进一次事件 { //这样每条记录就只执行一次 }
新功能:5.1.2-preview05
db.Aop.DataExecuted = (value, entity) => { if (entity.Entity.Type == typeof(Order)) { var newValue=entity.GetValue(nameof(Order.Name))+"111"; entity.SetValue(nameof(Order.Name), newValue); } }; //查询出来的值的 name都加上了 111 List<Order> list2 = db.Queryable<Order>().ToList();
2.1和2.2一起用就可以实现加密和解密字段
https://www.donet5.com/Home/Doc?typeId=1205
注意: 5.0.4.4 支持批量操作
Sql执行完后会进该事件,该事件可以拿到更改前记录和更改后记录,执行时间等参数(可以监控表变动)
该功能和 EF Core ChangeTracker 类似
db.Aop.OnDiffLogEvent = it => { //操作前记录 包含: 字段描述 列名 值 表名 表描述 var editBeforeData = it.BeforeData;//插入Before为null,之前还没进库 //操作后记录 包含: 字段描述 列名 值 表名 表描述 var editAfterData = it.AfterData; var sql = it.Sql; var parameter = it.Parameters; var data = it.BusinessData;//这边会显示你传进来的对象 var time = it.Time; var diffType=it.DiffType;//enum insert 、update and delete //Write logic }; db.Insertable(new Student() { Name = "beforeName" }) .EnableDiffLogEvent() //注意需要加上启用日志 .ExecuteReturnIdentity(); db.Updateable<Student>(new Student() { Id = id, CreateTime = DateTime.Now, Name = "afterName", SchoolId = 2 }) .EnableDiffLogEvent(new { title = "update Student", Modular = 1, Operator = "admin" }) //启用并传业务对象参数 .ExecuteCommand(); db.Deleteable<Student>(id) .EnableDiffLogEvent("删除学生") //启用传字符串业务参数 .ExecuteCommand();
这么改你所有操生成的sql表名前面就加了前缀 select * from "public"."表名"
return new SqlSugarClient(new ConnectionConfig() { DbType = SqlSugar.DbType.PostgreSQL, ConnectionString = Config.ConnectionString, InitKeyType = InitKeyType.Attribute, IsAutoCloseConnection = true, ConfigureExternalServices=new ConfigureExternalServices() { EntityNameService = (type, entity) => { entity.DbTableName = "public." + entity.DbTableName; } } });
上面只修改了表,如果我要表和列都修改呢
EntityNameService = (type, entity) => { //修改表 }, EntityService = (type, column) => { //修改列 }
SqlSugarClient db = new SqlSugarClient(new ConnectionConfig() { DbType = DbType.SqlServer, ConnectionString = Config.ConnectionString, InitKeyType = InitKeyType.Attribute, IsAutoCloseConnection = true }); db.Aop.OnLogExecuted = (sql, p) => { //执行时间超过1秒 if (db.Ado.SqlExecutionTime.TotalSeconds > 1) { //代码CS文件名 var fileName= db.Ado.SqlStackTrace.FirstFileName; //代码行数 var fileLine = db.Ado.SqlStackTrace.FirstLine; //方法名 var FirstMethodName = db.Ado.SqlStackTrace.FirstMethodName; //db.Ado.SqlStackTrace.MyStackTraceList[1].xxx 获取上层方法的信息 } //相当于EF的 PrintToMiniProfiler };
查看第4条 多租户-SqlSugar 5x-文档园 (donet5.com)
这个功能相当于替换ADO执行方法,已经超出来AOP的范畴
https://www.donet5.com/Home/Doc?typeId=2413
https://www.donet5.com/home/Doc?typeId=1205
2016 © donet5.comApache Licence 2.0