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

187 lines
7.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}