sqlsugar/Src/Asp.NetCore2/SqlSugar/Json2Sql/ModelToSql/FuncModelToSql.cs

187 lines
7.6 KiB
C#
Raw Normal View History

2025-05-11 16:20:50 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace SqlSugar
{
/// <summary>
///Json model to sql
/// </summary>
public abstract partial class SqlBuilderProvider : SqlBuilderAccessory, ISqlBuilder
{
#region Root
public KeyValuePair<string, SugarParameter[]> FuncModelToSql(IFuncModel model)
{
ObjectFuncModel data = model as ObjectFuncModel;
var name = data.FuncName;
var parameters = data.Parameters;
var dbMethods = this.Context.Queryable<object>().QueryBuilder.LambdaExpressions.DbMehtods;
var methods = GetAllMethods(dbMethods);
var methodName = GetMethodName(name, methods);
var methodInfo = GetMethod(dbMethods, methodName);
var pars = methodInfo.GetParameters();
var resSql = "";
var resPars = new List<SugarParameter>();
resSql = GetSql(parameters, dbMethods, methodName, methodInfo, pars, resPars);
if (name.EqualCase("MappingColumn"))
{
if (!(this.Context?. CurrentConnectionConfig?.MoreSettings?.EnableModelFuncMappingColumn == true))
{
Check.ExceptionEasy("Enable MappingColumn need in ConnectionConfig - > MoreSettings - > EnableModelFuncMappingColumn set to true", "MappingColumn考虑到风险情况需要开启才能使用请在 ConnectionConfig->MoreSettings->EnableModelFuncMappingColumn设置为true");
}
resSql = parameters.First() +"";
}
return new KeyValuePair<string, SugarParameter[]>(resSql, resPars.ToArray());
}
#endregion
#region Level2
private string GetSql(List<object> parameters, IDbMethods dbMethods, string methodName, System.Reflection.MethodInfo methodInfo, System.Reflection.ParameterInfo[] pars, List<SugarParameter> resPars)
{
string resSql;
if (IsNoParameter(pars))
{
resSql = GetNoParameterMehtodSql(dbMethods, methodInfo);
}
else if (IsFormatMethod(methodName))
{
resSql = GetFormatMethodSql(parameters, resPars);
}
else if (IsSqlFuncMethod(pars))
{
resSql = GetSqlFuncSql(parameters, dbMethods, methodName, methodInfo, resPars);
}
else if (IsMergeStringMethod(methodName))
{
resSql = GetSqlFuncSql(parameters, dbMethods, methodName, methodInfo, resPars);
}
else
{
resSql = GetNoSupportMethodSql(methodInfo);
}
return resSql;
}
private static System.Reflection.MethodInfo GetMethod(IDbMethods dbMethods, string methodName)
{
return dbMethods.GetType().GetMethods()
.Where(it => it.Name == methodName)
.Where(it => it.Name != "Equals" || it.GetParameters().Length == 1 && it.GetParameters().First().ParameterType == typeof(MethodCallExpressionModel))
.FirstOrDefault();
}
private static string GetMethodName(string name, List<string> methods)
{
var result = methods.FirstOrDefault(it => name.EqualCase("SqlFunc_" + it) || name.EqualCase(it));
Check.Exception(result == null, $" { name } is error ");
return result;
}
private static List<string> GetAllMethods(IDbMethods dbMethods)
{
return new ReflectionInoCacheService().GetOrCreate("Json2SqlGetFuncSql", () =>
dbMethods.GetType()
.GetMethods().Where(it => it.Name != "GetHashCode").Select(it => it.Name).ToList());
}
#endregion
#region Level3
private static string GetNoSupportMethodSql(System.Reflection.MethodInfo methodInfo)
{
throw new Exception(methodInfo.Name);
}
private string GetSqlFuncSql(List<object> parameters, IDbMethods dbMethods, string methodName, System.Reflection.MethodInfo methodInfo, List<SugarParameter> resPars)
{
string resSql;
var args = new List<MethodCallExpressionArgs>();
int i = 0;
foreach (var item in parameters)
{
i++;
string value = null;
if (methodName.IsIn("ContainsArray", "ContainsArrayUseSqlParameters") &&i==1)
{
var first = Regex.Split(item+"", ":").First();
var last = Regex.Split(item + "", ":").Last();
object[] array = this.Context.Utilities.DeserializeObject<object[]>(last);
value = GetParameterName(resPars, array);
}
else
{
value = GetSqlPart(item, resPars);
}
args.Add(new MethodCallExpressionArgs
{
MemberName = value,
MemberValue = resPars.FirstOrDefault(it => it.ParameterName == value)?.Value?? value,
IsMember = true
});
}
if (IsMergeStringMethod(methodName))
{
return methodInfo.Invoke(dbMethods, new object[] { args.Select(it=>it.MemberName.ObjToString()).ToArray() }).ObjToString();
}
if (IsToStringFormat(methodName, args))
{
var fieldName = args.First().MemberName.ObjToString();
var format = args.Last().MemberValue.ObjToString();
var queryable=this.Context.Queryable<object>()
.Select(it => SqlFunc.MappingColumn<DateTime>(fieldName).ToString(format));
var select=queryable.QueryBuilder.GetSelectValue;
return select;
}
resSql = methodInfo.Invoke(dbMethods, new object[] { new MethodCallExpressionModel() {
Name=methodName,
Args=args
} }).ObjToString();
return resSql;
}
private static bool IsToStringFormat(string methodName, List<MethodCallExpressionArgs> args)
{
return methodName == nameof(ToString) && args?.Count == 2;
}
private string GetFormatMethodSql(List<object> parameters, List<SugarParameter> resPars)
{
string resSql;
var objects = new List<string>();
foreach (var item in parameters)
{
var value = GetSqlPart(item, resPars);
objects.Add(value.ObjToString());
}
resSql = string.Join(" ", string.Join(" ", objects));
return resSql;
}
private static string GetNoParameterMehtodSql(IDbMethods dbMethods, System.Reflection.MethodInfo methodInfo)
{
return methodInfo.Invoke(dbMethods, new object[] { }).ObjToString();
}
#endregion
#region Helper
private static bool IsMergeStringMethod(string methodName)
{
return methodName == "MergeString";
}
private static bool IsSqlFuncMethod(System.Reflection.ParameterInfo[] pars)
{
return pars.First().ParameterType == typeof(MethodCallExpressionModel);
}
private static bool IsFormatMethod(string methodName)
{
return methodName.EqualCase("format");
}
private static bool IsNoParameter(System.Reflection.ParameterInfo[] pars)
{
return pars.Length == 0;
}
#endregion
}
}