注意:Aop一定要设置在你操作语句之前,不然不会生效,还有必须是同一个SqlSuagrClient才会有效
public SqlSugarClient GetInstance()
{
SqlSugarClient Db= new SqlSugarClient(new ConnectionConfig()
{
ConnectionString = "Server=.xxxxx",
DbType = DbType.SqlServer,
IsAutoCloseConnection = true,
InitKeyType = InitKeyType.Attribute
},db=>{
//如果是多库看标题6
//每次Sql执行前事件
db.Aop.OnLogExecuting = (sql, pars) =>
{
//我可以在这里面写逻辑
//技巧:AOP中获取IOC对象
//var serviceBuilder = services.BuildServiceProvider();
//var log= serviceBuilder.GetService<ILogger<WeatherForecastController>>();
};
});
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执行前
{
//获取原生SQL推荐 5.1.4.63 性能OK
//UtilMethods.GetNativeSql(sql,pars)
//获取无参数化SQL 影响性能只适合调试
//UtilMethods.GetSqlString(DbType.SqlServer,sql,pars)
};
db.Aop.OnError = (exp) =>//SQL报错
{
//获取原生SQL推荐 5.1.4.63 性能OK
//UtilMethods.GetNativeSql(exp.sql,exp.parameters)
//获取无参数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);
};只支持实体操作
//增、删、改 前和后 ,DataExecuting 和 DataChangesExecuted 用法一样 //2.1-2.3详细介绍 DataExecuting //前 DataChangesExecuted//后( 5.1.4.159版本才支持 用法和 DataExecuting 一样) //查询完对数据进行加工事件 //2.4有详细介绍 DataExecuted
这个事件可以操作 增(标题2.1) 、改(标题2.2) 和 删(标题2.3)
db.Aop.DataExecuting = (oldValue, entityInfo) =>
{
/*** 列级别事件:插入的每个列都会进事件 ***/
if (entityInfo.PropertyName == "CreateTime"&&entityInfo.OperationType== DataFilterType.InsertByObject)
{
entityInfo.SetValue(DateTime.Now);//修改CreateTime字段
/*entityInfo有字段所有参数*/
/*oldValue表示当前字段值 等同于下面写法*/
//var value=entityInfo.EntityColumnInfo.PropertyInfo.GetValue(entityInfo.EntityValue);
/*获取当前列特性*/
//5.1.3.23 +
//entityInfo.IsAnyAttribute<特性>()
//entityInfo.GetAttribute<特性>()
}
/*** 行级别事件 :一条记录只会进一次 ***/
if(entityInfo.EntityColumnInfo.IsPrimarykey)
{
//entityInfo.EntityValue 拿到单条实体对象
}
//可以写多个IF
};
/***只能是实体插入***/
db.Insertable(T).ExecuteReturnIdentity();
db.Insertable(List<T>).ExecuteReturnIdentity();这个事件可以操作 增(标题2.1) 、改(标题2.2) 和 删(标题2.3)
db.Aop.DataExecuting = (oldValue, entityInfo) =>
{
/*** 列级别事件 :更新的每一列都会进事件 ***/
if (entityInfo.PropertyName =="UpdateTime" && entityInfo.OperationType == DataFilterType.UpdateByObject)
{
entityInfo.SetValue(DateTime.Now);//修改UpdateTime字段
/*当前列获取特性*/
//5.1.3.23 +
//entityInfo.IsAnyAttribute<特性>()
//entityInfo.GetAttribute<特性>()
}
/*** 行级别事件 :更新一条记录只进一次 ***/
if(entityInfo.EntityColumnInfo.IsPrimarykey)
{
//entityInfo.EntityValue 拿到单条实体对象
}
/*** 根据当前列修改另一列 ***/
//if(当前列逻辑==XXX)
//var properyDate = entityInfo.EntityValue.GetType().GetProperty("Date");
//if(properyDate!=null)
//properyDate.SetValue(entityInfo.EntityValue,1);
//可以写多个IF
};
/***实体方式更新***/
db.Updateable(data).ExecuteCommand();
db.Updateable(dataList).ExecuteCommand();
//指定列更追加过滤器(5.1.4.106-Preview19+)
db.Updateable(updateObj).UpdateColumns(it=>new {it.Name},true).ExecuteCommand()
/***表达式方式更新***/
//新功能 5.1.3.2:表达式更新支持数据过滤器
db.Updateable<Order>()
.SetColumns(it => new Order(){ Name="A" }
,appendColumnsByDataFilter:true)//true表式追加过滤器赋值字段
.Where(it=>it.Id==1).ExecuteCommand()这个事件可以操作 增(标题2.1) 、改(标题2.2) 和 删(标题2.3)
db.Aop.DataExecuting = (oldValue, entityInfo) =>
{
/*** 删除生效 (只有行级事件) ***/
if (entityInfo.OperationType == DataFilterType.DeleteByObject)
{
//entityInfo.EntityValue 拿到所有实体对象
}
//可以写多个IF
}
/***只能是实体删除***/
db.Deleteable(List<T>).ExecCommand();//实体集合有效
db.Deleteable(T).ExecCommand();//实体有效新功能: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 和 2.4 一起用就可以实现加密和解密字段 或者 自定义类型实现
https://www.donet5.com/Home/Doc?typeId=1205
ORM中唯一支持:触发器、默认值的审计 ,在多家上市公司项目得到实践交付
注意: 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();只获取差异部分
https://www.donet5.com/ask/9/23905
升级到:5.1.4.73-preview05
//程序启动时注册
StaticConfig.CompleteInsertableFunc=
StaticConfig.CompleteUpdateableFunc=
StaticConfig.CompleteDeleteableFunc = it => //it是具体的对象Updateable<T>等是个object
{
//反射的方法可能多个就需要用GetMethods().Where
var method = it.GetType().GetMethod("EnableDiffLogEvent");
method.Invoke(it,new object[] { null });
//技巧:
//可以定义一个接口只要是这个接口的才走这个逻辑
//if(db.GetType().GenericTypeArguments[0].GetInterfaces().Any(it=>it==typeof(IDiff))
//可以根据类型写if
//if(x.GetType().GenericTypeArguments[0] = typeof(Order)) { }
};
//注册完就
//Insertable、Updateable和Deleteable就会自动调用EnableDiffLogEvent()
//不需一个一个写
这么改你所有操生成的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) =>
{
//修改列
}是指sql命令执行完的时间
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
};注意:事件不要写错了,写错可能会出现负数,要执行后事件,不能是执行前
是指Sql命令执行+绑定实体的时间
db.Aop.OnGetDataReadered = (sql, pars,time) =>
{
//5.1.4.173-preview06+
//DataReader绑定时间
};是指SqlConnection.Open()的时间
db.Aop.CheckConnectionExecuted = (conn, time) =>
{
//5.1.4.173-preview06+
//Connection.Open()结束事件
};//只能在OnLogExecuted事件中使用
db.Aop.OnLogExecuted = (sql, p) =>
{
var count=db.Ado.SqlExecuteCount;
if(count>0)
{
}
}/***注意***/
//如果你用的 GetConnectionScope或者 GetConnectionScopeWithAttr AOP也应该用 GetConnectionScope
//如果你用的 GetConnection或者 GetConnectionWithAttr AOP也应该用 GetConnectionScope
SqlSugarClient Db= new SqlSugarClient(new ConnectionConfig(){
ConnectionString = "连接符字串",
DbType = DbType.SqlServer,
IsAutoCloseConnection = true},
db=>{
//也可以这里面循环
db.GetConnection("1").Aop.OnLogExecuting = (sql, pars) =>
{
Console.WriteLine("执行1库"+sql);
};
db.GetConnection("0").Aop.OnLogExecuting = (sql, pars) =>
{
Console.WriteLine("执行0库"+sql);
};
});这个功能相当于替换ADO执行方法,已经超出来AOP的范畴
https://www.donet5.com/Home/Doc?typeId=2413
https://www.donet5.com/home/Doc?typeId=1205
//建一个扩展类
public static class SqlsugarSetup
{
public static void AddSqlsugarSetup(this IServiceCollection services, IConfiguration configuration,
string dbName = "db_master")
{
SqlSugarScope sqlSugar = new SqlSugarScope(new ConnectionConfig()
{
DbType = SqlSugar.DbType.MySql,
ConnectionString = configuration.GetConnectionString(dbName),
IsAutoCloseConnection = true,
},
db =>
{
//技巧:拿到非ORM注入对象
var serviceBuilder = services.BuildServiceProvider();
var log= serviceBuilder.GetService<类>();
});
services.AddSingleton<ISqlSugarClient>(sqlSugar);//这边是SqlSugarScope用AddSingleton
}
}
//Startup.cs文件添加下面代码
services.AddSqlsugarSetup(Configuration);
//业务类和仓储对象不能用单例(只有SqlSugarScope注入单例其他不要单例)升级到:5.1.4.73-preview05
可以针对Queryable Insertable Updateable Deleteable ISqlSugarClient对象创建完得行全局修改
CompleteQueryableFunc:Queryable创建完事件
CompleteInsertableFunc: Insertable创建完事件
CompleteUpdateableFunc: Updateable创建完事件
CompleteDeleteableFunc: Deleteable创建完事件
CompleteDbFunc: ISqlSugarClient创建完事件
写个用例:
//程序启动时注册
StaticConfig.CompleteInsertableFunc= it => //it是具体的对象Insertable<T>等是个object
{
//反射的方法可能多个就需要用GetMethods().Where
var method = it.GetType().GetMethod("EnableDiffLogEvent");
method.Invoke(it,new object[] { null });
//技巧:
//可以定义一个接口只要是这个接口的才走这个逻辑
//if(db.GetType().GenericTypeArguments[0].GetInterfaces().Any(it=>it==typeof(IDiff))
};
//注册完就自动调用.EnableDiffLogEvent()
db.Insertable(list).Execommand();
//等同于
// db.Insertable(list).EnableDiffLogEvent().Execommand();使用全局注入AOP
//程序启动时注册
StaticConfig.CompleteDbFunc=db=>
{
db.Aop.xxx=xxx
}2016 © donet5.comApache Licence 2.0