mirror of
https://github.com/nsnail/FreeSql.git
synced 2025-06-19 20:38:16 +08:00
SQL命令执行监视 + Pgsql表达式(Array/HStore/Jsonb)实现与测试
This commit is contained in:
@ -222,6 +222,8 @@ namespace FreeSql.Internal {
|
||||
case "Min": return $"min({ExpressionLambdaToSql(exp3.Arguments[0], _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName)})";
|
||||
}
|
||||
}
|
||||
var other3Exp = ExpressionLambdaToSqlOther(exp3, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||
if (string.IsNullOrEmpty(other3Exp) == false) return other3Exp;
|
||||
throw new Exception($"未现实函数表达式 {exp3} 解析");
|
||||
case ExpressionType.MemberAccess:
|
||||
var exp4 = exp as MemberExpression;
|
||||
@ -234,6 +236,8 @@ namespace FreeSql.Internal {
|
||||
case "System.TimeSpan": extRet = ExpressionLambdaToSqlMemberAccessTimeSpan(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName); break;
|
||||
}
|
||||
if (string.IsNullOrEmpty(extRet) == false) return extRet;
|
||||
var other4Exp = ExpressionLambdaToSqlOther(exp4, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||
if (string.IsNullOrEmpty(other4Exp) == false) return other4Exp;
|
||||
|
||||
var expStack = new Stack<Expression>();
|
||||
expStack.Push(exp);
|
||||
@ -341,7 +345,11 @@ namespace FreeSql.Internal {
|
||||
return $"{alias2}.{name2}";
|
||||
}
|
||||
var expBinary = exp as BinaryExpression;
|
||||
if (expBinary == null) return "";
|
||||
if (expBinary == null) {
|
||||
var other99Exp = ExpressionLambdaToSqlOther(exp, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName);
|
||||
if (string.IsNullOrEmpty(other99Exp) == false) return other99Exp;
|
||||
return "";
|
||||
}
|
||||
if (expBinary.NodeType == ExpressionType.Coalesce) {
|
||||
return _common.IsNull(
|
||||
ExpressionLambdaToSql(expBinary.Left, _tables, _selectColumnMap, getSelectGroupingMapString, tbtype, isQuoteName),
|
||||
@ -368,5 +376,6 @@ namespace FreeSql.Internal {
|
||||
internal abstract string ExpressionLambdaToSqlCallDateTime(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName);
|
||||
internal abstract string ExpressionLambdaToSqlCallTimeSpan(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName);
|
||||
internal abstract string ExpressionLambdaToSqlCallConvert(MethodCallExpression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName);
|
||||
internal abstract string ExpressionLambdaToSqlOther(Expression exp, List<SelectTableInfo> _tables, List<SelectColumnInfo> _selectColumnMap, Func<Expression[], string> getSelectGroupingMapString, SelectTableInfoType tbtype, bool isQuoteName);
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,8 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
protected abstract void ReturnConnection(ObjectPool<DbConnection> pool, Object<DbConnection> conn, Exception ex);
|
||||
protected abstract DbCommand CreateCommand();
|
||||
protected abstract DbParameter[] GetDbParamtersByObject(string sql, object obj);
|
||||
internal Action<DbCommand> AopCommandExecuting = null;
|
||||
internal Action<DbCommand, string> AopCommandExecuted = null;
|
||||
|
||||
public bool IsTracePerformance { get; set; } = string.Compare(Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"), "Development", true) == 0;
|
||||
|
||||
@ -32,10 +34,14 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
if (IsTracePerformance) {
|
||||
TimeSpan ts = DateTime.Now.Subtract(dt);
|
||||
if (e == null && ts.TotalMilliseconds > 100)
|
||||
_log.LogWarning($"{pool.Policy.Name}执行SQL语句耗时过长{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n{logtxt}");
|
||||
_log.LogWarning(logtxt = $"{pool.Policy.Name}执行SQL语句耗时过长{ts.TotalMilliseconds}ms\r\n{cmd.CommandText}\r\n{logtxt}");
|
||||
}
|
||||
|
||||
if (e == null) {
|
||||
AopCommandExecuted?.Invoke(cmd, logtxt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e == null) return;
|
||||
string log = $"{pool.Policy.Name}数据库出错(执行SQL)〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓\r\n{cmd.CommandText}\r\n";
|
||||
foreach (DbParameter parm in cmd.Parameters)
|
||||
log += parm.ParameterName.PadRight(20, ' ') + " = " + ((parm.Value ?? DBNull.Value) == DBNull.Value ? "NULL" : parm.Value) + "\r\n";
|
||||
@ -44,6 +50,9 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
_log.LogError(log);
|
||||
|
||||
RollbackTransaction();
|
||||
|
||||
AopCommandExecuted?.Invoke(cmd, log);
|
||||
|
||||
cmd.Parameters.Clear();
|
||||
if (isThrowException) throw e;
|
||||
}
|
||||
@ -261,6 +270,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
AutoCommitTransaction();
|
||||
if (IsTracePerformance) logtxt += $" AutoCommitTransaction: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n";
|
||||
|
||||
AopCommandExecuting?.Invoke(cmd);
|
||||
return (tran, cmd);
|
||||
}
|
||||
}
|
||||
|
@ -209,6 +209,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
if (IsTracePerformance) logtxt += $" PrepareCommand_tran==null: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms cmdParms: {cmd.Parameters.Count}\r\n";
|
||||
|
||||
AopCommandExecuting?.Invoke(cmd);
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
|
@ -210,13 +210,13 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
protected (ReadAnonymousTypeInfo map, string field) GetNewExpressionField(NewExpression newexp) {
|
||||
protected (ReadAnonymousTypeInfo map, string field) GetExpressionField(Expression newexp) {
|
||||
var map = new ReadAnonymousTypeInfo();
|
||||
var field = new StringBuilder();
|
||||
var index = 0;
|
||||
|
||||
_commonExpression.ReadAnonymousField(_tables, field, map, ref index, newexp, null);
|
||||
return (map, map.Childs.Count > 0 ? field.Remove(0, 2).ToString() : null);
|
||||
return (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null);
|
||||
}
|
||||
protected (ReadAnonymousTypeInfo map, string field) GetAllField() {
|
||||
var type = typeof(T1);
|
||||
@ -281,7 +281,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
var index = -10000; //临时规则,不返回 as1
|
||||
|
||||
_commonExpression.ReadAnonymousField(_tables, field, map, ref index, columns, null);
|
||||
this.GroupBy(map.Childs.Count > 0 ? field.Remove(0, 2).ToString() : null);
|
||||
this.GroupBy(field.Length > 0 ? field.Remove(0, 2).ToString() : null);
|
||||
return new SelectGroupingProvider<TKey>(this, map, _commonExpression);
|
||||
}
|
||||
protected TSelect InternalJoin(Expression exp, SelectTableInfoType joinType) {
|
||||
@ -298,9 +298,12 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
protected TSelect InternalOrderBy(Expression column) => this.OrderBy(_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null));
|
||||
protected TSelect InternalOrderByDescending(Expression column) => this.OrderBy($"{_commonExpression.ExpressionSelectColumn_MemberAccess(_tables, null, SelectTableInfoType.From, column, true, null)} DESC");
|
||||
|
||||
protected List<TReturn> InternalToList<TReturn>(Expression select) => this.ToListMapReader<TReturn>(this.GetNewExpressionField(select as NewExpression));
|
||||
protected Task<List<TReturn>> InternalToListAsync<TReturn>(Expression select) => this.ToListMapReaderAsync<TReturn>(this.GetNewExpressionField(select as NewExpression));
|
||||
protected string InternalToSql<TReturn>(Expression select) => this.ToSql(this.GetNewExpressionField(select as NewExpression).field);
|
||||
protected List<TReturn> InternalToList<TReturn>(Expression select) => this.ToListMapReader<TReturn>(this.GetExpressionField(select));
|
||||
protected Task<List<TReturn>> InternalToListAsync<TReturn>(Expression select) => this.ToListMapReaderAsync<TReturn>(this.GetExpressionField(select));
|
||||
protected string InternalToSql<TReturn>(Expression select) {
|
||||
var af = this.GetExpressionField(select);
|
||||
return this.ToSql(af.field);
|
||||
}
|
||||
|
||||
protected TReturn InternalToAggregate<TReturn>(Expression select) {
|
||||
var map = new ReadAnonymousTypeInfo();
|
||||
@ -308,7 +311,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
var index = 0;
|
||||
|
||||
_commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null);
|
||||
return this.ToListMapReader<TReturn>((map, map.Childs.Count > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault();
|
||||
return this.ToListMapReader<TReturn>((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null)).FirstOrDefault();
|
||||
}
|
||||
async protected Task<TReturn> InternalToAggregateAsync<TReturn>(Expression select) {
|
||||
var map = new ReadAnonymousTypeInfo();
|
||||
@ -316,7 +319,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
var index = 0;
|
||||
|
||||
_commonExpression.ReadAnonymousField(_tables, field, map, ref index, select, null);
|
||||
return (await this.ToListMapReaderAsync<TReturn>((map, map.Childs.Count > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault();
|
||||
return (await this.ToListMapReaderAsync<TReturn>((map, field.Length > 0 ? field.Remove(0, 2).ToString() : null))).FirstOrDefault();
|
||||
}
|
||||
|
||||
protected TSelect InternalWhere(Expression exp) => this.Where(_commonExpression.ExpressionWhereLambda(_tables, exp, null));
|
||||
|
@ -57,7 +57,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
_comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString);
|
||||
var method = _select.GetType().GetMethod("ToListMapReader", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
method = method.MakeGenericMethod(typeof(TReturn));
|
||||
return method.Invoke(_select, new object[] { (map, map.Childs.Count > 0 ? field.Remove(0, 2).ToString() : null) }) as List<TReturn>;
|
||||
return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as List<TReturn>;
|
||||
}
|
||||
public Task<List<TReturn>> ToListAsync<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, TReturn>> select) {
|
||||
var map = new ReadAnonymousTypeInfo();
|
||||
@ -67,7 +67,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
_comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString);
|
||||
var method = _select.GetType().GetMethod("ToListMapReaderAsync", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
method = method.MakeGenericMethod(typeof(TReturn));
|
||||
return method.Invoke(_select, new object[] { (map, map.Childs.Count > 0 ? field.Remove(0, 2).ToString() : null) }) as Task<List<TReturn>>;
|
||||
return method.Invoke(_select, new object[] { (map, field.Length > 0 ? field.Remove(0, 2).ToString() : null) }) as Task<List<TReturn>>;
|
||||
}
|
||||
|
||||
public string ToSql<TReturn>(Expression<Func<ISelectGroupingAggregate<T1>, TReturn>> select) {
|
||||
@ -77,7 +77,7 @@ namespace FreeSql.Internal.CommonProvider {
|
||||
|
||||
_comonExp.ReadAnonymousField(null, field, map, ref index, select, getSelectGroupingMapString);
|
||||
var method = _select.GetType().GetMethod("ToSql", new[] { typeof(string) });
|
||||
return method.Invoke(_select, new object[] { map.Childs.Count > 0 ? field.Remove(0, 2).ToString() : null }) as string;
|
||||
return method.Invoke(_select, new object[] { field.Length > 0 ? field.Remove(0, 2).ToString() : null }) as string;
|
||||
}
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user