using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace SqlSugar
{
///
///MethodCall Helper
///
public partial class MethodCallExpressionResolve : BaseResolve
{
private void CusMethod(ExpressionParameter parameter, MethodCallExpression express, bool? isLeft)
{
try
{
OneToManyNavgateExpression nav = new OneToManyNavgateExpression(this.Context?.SugarContext?.Context, this);
nav.ParameterIndex = this.Context.ParameterIndex;
this.Context.ParameterIndex++;
if (nav.IsNavgate(express))
{
var sql = nav.GetSql();
SetNavigateResult();
this.Context.SingleTableNameSubqueryShortName = nav.ShorName;
base.AppendValue(parameter, isLeft, sql);
return;
}
OneToManyNavgateExpressionN nav2 = new OneToManyNavgateExpressionN(this.Context?.SugarContext?.Context, this);
if (nav2.IsNavgate(express))
{
var sql = nav2.GetSql();
SetNavigateResult();
this.Context.SingleTableNameSubqueryShortName = nav2.shorName;
base.AppendValue(parameter, isLeft, sql);
return;
}
var constValue = ExpressionTool.DynamicInvoke(express);
if (constValue is MapperSql)
{
constValue = (constValue as MapperSql).Sql;
base.AppendValue(parameter, isLeft, constValue);
return;
}
parameter.BaseParameter.CommonTempData = constValue;
var parameterName = base.AppendParameter(constValue);
if (parameter.BaseParameter.CommonTempData != null && parameter.BaseParameter.CommonTempData.Equals(CommonTempDataType.Result))
{
this.Context.Result.Append(parameterName);
}
else
{
base.AppendValue(parameter, isLeft, parameterName);
}
}
catch (Exception ex)
{
if (ex is SqlSugarException)
{
Check.Exception(true, string.Format(ex.Message, express.Method.Name));
}
else
{
Check.Exception(true, string.Format(ErrorMessage.MethodError, express.Method.Name));
}
}
}
private static bool MethodValueIsTrue(object methodValue)
{
return methodValue != null && methodValue.ToString().Contains("THEN true ELSE false END");
}
private object packIfElse(object methodValue)
{
methodValue = this.Context.DbMehtods.CaseWhen(new List>() {
new KeyValuePair("IF",methodValue.ObjToString()),
new KeyValuePair("Return", this.Context.DbMehtods.TrueValue()),
new KeyValuePair("End", this.Context.DbMehtods.FalseValue())
});
return methodValue;
}
private void SetShortName(Expression exp)
{
var lamExp = (exp as LambdaExpression);
if (lamExp.Parameters != null && lamExp.Parameters.Count == 1)
{
if (this.Context.SingleTableNameSubqueryShortName == null)
{
this.Context.SingleTableNameSubqueryShortName = lamExp.Parameters.First().Name;
}
}
}
private void AppendItem(ExpressionParameter parameter, string name, IEnumerable args, MethodCallExpressionModel model, Expression item)
{
if (ExpressionTool.IsUnConvertExpress(item))
{
item = (item as UnaryExpression).Operand;
}
if (this.Context.IsSingle && args.Any(it => ExpressionTool.IsSubQuery(it)) && base.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression != null)
{
var exp = base.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression;
if (exp is LambdaExpression)
{
SetShortName(exp);
}
else if (exp is UnaryExpression)
{
exp = base.BaseParameter?.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression;
if (exp is LambdaExpression)
{
SetShortName(exp);
}
}
}
else if (this.Context.IsSingle && args.Any(it => ExpressionTool.IsIsNullSubQuery(it)))
{
var exp = base.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression;
if (exp is LambdaExpression)
{
SetShortName(exp);
}
else if (exp is UnaryExpression)
{
exp = base.BaseParameter?.BaseParameter?.BaseParameter?.BaseParameter?.CurrentExpression;
if (exp is LambdaExpression)
{
SetShortName(exp);
}
}
}
var isBinaryExpression = item is BinaryExpression || item is MethodCallExpression;
var isConst = item is ConstantExpression;
var isIIF = name == "IIF";
var isSubIIF = (isIIF && item.ToString().StartsWith("IIF"));
var isIFFBoolMember = isIIF && (item is MemberExpression) && (item as MemberExpression).Type == UtilConstants.BoolType;
var isIFFUnary = isIIF && (item is UnaryExpression) && (item as UnaryExpression).Operand.Type == UtilConstants.BoolType;
var isIFFBoolBinary = isIIF && (item is BinaryExpression) && (item as BinaryExpression).Type == UtilConstants.BoolType;
var isIFFBoolMethod = isIIF && (item is MethodCallExpression) && (item as MethodCallExpression).Type == UtilConstants.BoolType;
var isFirst = item == args.First();
var isBoolValue = item.Type == UtilConstants.BoolType && item.ToString().StartsWith("value(");
var isLength =ExpressionTool.GetIsLength(item);
if (isFirst && isIIF && isConst)
{
var value = (item as ConstantExpression).Value.ObjToBool() ? this.Context.DbMehtods.True() : this.Context.DbMehtods.False();
var methodCallExpressionArgs = new MethodCallExpressionArgs()
{
IsMember = true,
MemberName = value,
MemberValue = value
};
model.Args.Add(methodCallExpressionArgs);
}
else if (isFirst && isIIF && isIFFBoolMember && (item as MemberExpression)?.Member?.Name == "HasValue")
{
var value = base.GetNewExpressionValue(item);
var methodCallExpressionArgs = new MethodCallExpressionArgs()
{
IsMember = true,
MemberName = value,
MemberValue = value
};
model.Args.Add(methodCallExpressionArgs);
}
else if (name != null && name != "MappingColumn" && !name.StartsWith("Row") && ExpressionTool.GetMethodName(item) == "Format" && ExpressionTool.GetParameters(item).Count == 0)
{
var value = ExpressionTool.DynamicInvoke(item);
var p = AppendParameter(value);
var methodCallExpressionArgs = new MethodCallExpressionArgs()
{
IsMember = true,
MemberName = p,
MemberValue = p
};
model.Args.Add(methodCallExpressionArgs);
}
else if (isLength)
{
var value = GetNewExpressionValue(item);
var methodCallExpressionArgs = new MethodCallExpressionArgs()
{
IsMember = true,
MemberName = value,
MemberValue = value
};
model.Args.Add(methodCallExpressionArgs);
}
else if (isIFFUnary && !isFirst)
{
AppendModelByIIFMember(parameter, model, (item as UnaryExpression).Operand);
}
else if (isIFFBoolMember && !isFirst)
{
AppendModelByIIFMember(parameter, model, item);
}
else if (isIFFBoolBinary && !isFirst)
{
var binaryExp = item as BinaryExpression;
var binaryExpEqual = binaryExp != null && ExpressionTool.IsComparisonOperatorBool(binaryExp);
if (binaryExpEqual)
{
var expValue = GetNewExpressionValue(item);
expValue = this.Context.DbMehtods.IIF(new MethodCallExpressionModel()
{
Name = "IIF",
Args = new List()
{
new MethodCallExpressionArgs(){
IsMember=true,
MemberName=expValue
},
new MethodCallExpressionArgs(){
IsMember=true,
MemberName= Context.DbMehtods.TrueValue()
},
new MethodCallExpressionArgs(){
IsMember=true,
MemberName= Context.DbMehtods.FalseValue()
}
}
});
model.Args.Add(new MethodCallExpressionArgs()
{
IsMember = false,
MemberName = expValue,
MemberValue = expValue
});
}
else
{
AppendModelByIIFBinary(parameter, model, item);
}
}
else if (isIFFBoolMethod && !isFirst)
{
AppendModelByIIFMethod(parameter, model, item);
}
else if (isBinaryExpression)
{
model.Args.Add(GetMethodCallArgs(parameter, item, name));
}
else if (isSubIIF)
{
model.Args.Add(GetMethodCallArgs(parameter, item));
}
else if (isBoolValue && !isIIF && item is MemberExpression)
{
model.Args.Add(GetMethodCallArgs(parameter, (item as MemberExpression).Expression));
}
else if (isBoolValue && isIIF && item is MemberExpression&&ExpressionTool.GetParameters(item).Count()==0)
{
var expValue = AppendParameter(ExpressionTool.DynamicInvoke(item));
expValue = this.Context.DbMehtods.Equals(new MethodCallExpressionModel()
{
Name = "Equals",
Args = new List()
{
new MethodCallExpressionArgs(){
IsMember=true,
MemberName=expValue
},
new MethodCallExpressionArgs(){
IsMember=true,
MemberName= Context.DbMehtods.TrueValue()
}
}
});
model.Args.Add(new MethodCallExpressionArgs()
{
IsMember = false,
MemberName = expValue,
MemberValue = expValue
});
}
else if (isBoolValue && isIIF && item is MemberExpression)
{
var argItem = GetMethodCallArgs(parameter, (item as MemberExpression).Expression);
if (argItem.IsMember)
{
var pName = this.Context.SqlParameterKeyWord + "true_0";
if (!this.Context.Parameters.Any(it => it.ParameterName == pName))
this.Context.Parameters.Add(new SugarParameter(pName, true));
argItem.MemberName = $" {argItem.MemberName}={pName} ";
}
model.Args.Add(argItem);
}
else if (name.IsIn("ListAny", "ListAll") && item is LambdaExpression)
{
var sql = GetNewExpressionValue(item, ResolveExpressType.WhereMultiple);
var lamExp = (item as LambdaExpression);
var pExp = lamExp.Parameters[0];
var pname = pExp.Name;
model.Args.Add(new MethodCallExpressionArgs()
{
MemberValue = new ListAnyParameter()
{
Sql = sql,
Name = pname,
Columns = this.Context.SugarContext.Context.EntityMaintenance.GetEntityInfo(pExp.Type).Columns,
ConvetColumnFunc = this.Context.GetTranslationColumnName
}
});
if (this.Context.IsSingle && this.Context.SingleTableNameSubqueryShortName == null)
{
ParameterExpressionVisitor visitor = new ParameterExpressionVisitor();
visitor.Visit(lamExp);
var tableParamter = visitor.Parameters.FirstOrDefault(it => it.Name != pname);
if (tableParamter != null)
{
this.Context.SingleTableNameSubqueryShortName = tableParamter.Name;
}
}
}
else
{
AppendModel(parameter, model, item, name, args);
}
}
private void AppendModelByIIFMember(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item)
{
parameter.CommonTempData = CommonTempDataType.Result;
base.Expression = item;
base.Start();
var methodCallExpressionArgs = new MethodCallExpressionArgs()
{
IsMember = parameter.ChildExpression is MemberExpression,
MemberName = parameter.CommonTempData
};
if (methodCallExpressionArgs.IsMember && parameter.ChildExpression != null && parameter.ChildExpression.ToString() == "DateTime.Now")
{
methodCallExpressionArgs.IsMember = false;
}
var value = methodCallExpressionArgs.MemberName;
if (methodCallExpressionArgs.IsMember)
{
var childExpression = parameter.ChildExpression as MemberExpression;
if (childExpression.Expression != null && childExpression.Expression is ConstantExpression)
{
methodCallExpressionArgs.IsMember = false;
}
}
if (methodCallExpressionArgs.IsMember == false)
{
var parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.MethodConst + this.Context.ParameterIndex;
this.Context.ParameterIndex++;
methodCallExpressionArgs.MemberName = parameterName;
methodCallExpressionArgs.MemberValue = value;
this.Context.Parameters.Add(new SugarParameter(parameterName, value));
}
model.Args.Add(methodCallExpressionArgs);
parameter.ChildExpression = null;
}
private void AppendModelByIIFBinary(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item)
{
Check.Exception(true, "The SqlFunc.IIF(arg1,arg2,arg3) , {0} argument do not support ", item.ToString());
}
private void AppendModelByIIFMethod(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item)
{
var methodExpression = item as MethodCallExpression;
if (methodExpression.Method.Name.IsIn("ToBool", "ToBoolean", "IIF"))
{
model.Args.Add(base.GetMethodCallArgs(parameter, item));
}
else if (methodExpression.Method.Name.IsIn("Contains", "EndsWith", "StartsWith"))
{
Expression conditionalExpression =ExpressionTool.GetConditionalExpression(item);
model.Args.Add(base.GetMethodCallArgs(parameter, conditionalExpression));
}
else
{
Check.Exception(true, "The SqlFunc.IIF(arg1,arg2,arg3) , {0} argument do not support ", item.ToString());
}
}
private void AppendModel(ExpressionParameter parameter, MethodCallExpressionModel model, Expression item,string name, IEnumerable args)
{
parameter.CommonTempData = CommonTempDataType.Result;
base.Expression = item;
var isRemoveParamter = false;
var isNegate = false;
if (item.Type == UtilConstants.DateType && parameter.CommonTempData.ObjToString() == CommonTempDataType.Result.ToString() && item.ToString() == "DateTime.Now.Date")
{
parameter.CommonTempData = DateTime.Now.Date;
}
else if (item is ConditionalExpression)
{
parameter.CommonTempData = GetNewExpressionValue(item);
}
else if (IsNot(item))
{
parameter.CommonTempData = GetNewExpressionValue(item);
}
else if (IsDateDate(item))
{
parameter.CommonTempData = GetNewExpressionValue(item);
}
else if (IsDateValue(item))
{
parameter.CommonTempData = GetNewExpressionValue(item);
}
else if (model.Name == "ToString" && item is ConstantExpression && (item as ConstantExpression).Type.IsEnum())
{
parameter.CommonTempData = item.ToString();
}
else if (IsDateItemValue(item))
{
parameter.CommonTempData = GetNewExpressionValue(item);
}
else if (name == "Format" && item is NewArrayExpression)
{
var exps = (item as NewArrayExpression).Expressions;
parameter.CommonTempData = exps.Select(it =>
{
var res = GetNewExpressionValue(ExpressionTool.RemoveConvert(it));
return res;
}).ToArray();
}
else if (name == "Format" && item is ConstantExpression)
{
parameter.CommonTempData = ExpressionTool.GetExpressionValue(item);
}
else if (name == "FullTextContains" && item is NewArrayExpression)
{
var array = ExpressionTool.GetNewArrayMembers(item as NewArrayExpression);
parameter.CommonTempData = array.Select(it=>this.Context.GetTranslationColumnName(it)).ToList();
isRemoveParamter = true;
}
else if (ExpressionTool.IsNegate(item) && (item as UnaryExpression)?.Operand is MemberExpression)
{
var exp = (item as UnaryExpression)?.Operand;
parameter.CommonTempData = GetNewExpressionValue(exp) + " * -1 ";
isRemoveParamter = true;
isNegate = true;
}
else
{
base.Start();
}
var methodCallExpressionArgs = new MethodCallExpressionArgs()
{
IsMember = parameter.ChildExpression is MemberExpression && !ExpressionTool.IsConstExpression(parameter.ChildExpression as MemberExpression),
MemberName = parameter.CommonTempData
};
if (this.Context?.SugarContext?.Context?.CurrentConnectionConfig?.MoreSettings?.IsCorrectErrorSqlParameterName == true)
{
if (methodCallExpressionArgs.MemberName is string)
{
methodCallExpressionArgs.MemberName = ExpressionTool.ResolveMemberValue(this.Context, item, methodCallExpressionArgs.MemberName?.ToString());
}
}
if (methodCallExpressionArgs.MemberName is MapperSql)
{
methodCallExpressionArgs.MemberName = (methodCallExpressionArgs.MemberName as MapperSql).Sql;
}
if (methodCallExpressionArgs.IsMember && parameter.ChildExpression != null && parameter.ChildExpression.ToString() == "DateTime.Now")
{
methodCallExpressionArgs.IsMember = false;
}
var value = methodCallExpressionArgs.MemberName;
if (methodCallExpressionArgs.IsMember)
{
var childExpression = parameter.ChildExpression as MemberExpression;
if (childExpression.Expression != null && childExpression.Expression is ConstantExpression)
{
methodCallExpressionArgs.IsMember = false;
}
}
if (IsDateDate(item) || IsDateValue(item) || IsDateItemValue(item) || item is ConditionalExpression || IsNot(item))
{
methodCallExpressionArgs.IsMember = true;
}
if (methodCallExpressionArgs.IsMember == false && (item is MethodCallExpression && item.ToString() == "GetDate()") || (item is UnaryExpression && ((UnaryExpression)item).Operand.ToString() == "GetDate()"))
{
var parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.MethodConst + this.Context.ParameterIndex;
this.Context.ParameterIndex++;
methodCallExpressionArgs.MemberName = value;
methodCallExpressionArgs.MemberValue = null;
}
else if (methodCallExpressionArgs.IsMember == false&&isNegate==false)
{
var parameterName = this.Context.SqlParameterKeyWord + ExpressionConst.MethodConst + this.Context.ParameterIndex;
this.Context.ParameterIndex++;
methodCallExpressionArgs.MemberName = parameterName;
if (name == "ToString"&&UtilMethods.GetUnderType(base.Expression.Type).IsEnum())
{
value = value?.ToString();
}
else if (name == "ContainsArray"&&args.Count()==2&& value!= null && value is IList)
{
List