2017-01-30 15:10:54 +08:00
using SqlSugar ;
using System ;
2019-06-09 20:51:57 +08:00
using System.Collections ;
2017-01-07 21:54:51 +08:00
using System.Collections.Generic ;
2017-06-14 00:20:41 +08:00
using System.Collections.ObjectModel ;
2017-01-07 21:54:51 +08:00
using System.Linq ;
using System.Linq.Expressions ;
using System.Text ;
2019-05-15 18:11:44 +08:00
using System.Text.RegularExpressions ;
2017-01-07 21:54:51 +08:00
namespace SqlSugar
{
2017-01-30 15:10:54 +08:00
public class MethodCallExpressionResolve : BaseResolve
2017-01-07 21:54:51 +08:00
{
2019-02-09 20:53:44 +08:00
int contextIndex = 0 ;
2017-01-07 23:56:55 +08:00
public MethodCallExpressionResolve ( ExpressionParameter parameter ) : base ( parameter )
2017-01-07 21:54:51 +08:00
{
2019-02-09 20:53:44 +08:00
contextIndex = this . Context . Index ;
2017-01-30 15:10:54 +08:00
var express = base . Expression as MethodCallExpression ;
2019-02-09 18:49:32 +08:00
if ( express = = null ) return ;
2017-01-31 20:13:22 +08:00
var isLeft = parameter . IsLeft ;
2017-06-14 01:00:16 +08:00
string methodName = express . Method . Name ;
2017-11-17 14:08:25 +08:00
var isValidNativeMethod = IsValidNativeMethod ( express , methodName ) ;
2017-07-16 04:35:42 +08:00
List < MethodCallExpressionArgs > appendArgs = null ;
if ( MethodTimeMapping . ContainsKey ( methodName ) )
{
appendArgs = new List < MethodCallExpressionArgs > ( ) ;
var dateType = MethodTimeMapping [ methodName ] ;
string paramterName = this . Context . SqlParameterKeyWord + ExpressionConst . Const + this . Context . ParameterIndex ;
2017-08-13 21:34:29 +08:00
appendArgs . Add ( new MethodCallExpressionArgs ( ) { IsMember = false , MemberName = paramterName , MemberValue = dateType } ) ;
2017-07-16 04:35:42 +08:00
this . Context . Parameters . Add ( new SugarParameter ( paramterName , dateType . ToString ( ) ) ) ;
this . Context . ParameterIndex + + ;
methodName = "DateAdd" ;
isValidNativeMethod = true ;
}
else if ( methodName = = "get_Item" )
2017-07-12 00:15:14 +08:00
{
string paramterName = this . Context . SqlParameterKeyWord + ExpressionConst . Const + this . Context . ParameterIndex ;
2017-06-27 16:25:36 +08:00
this . Context . Parameters . Add ( new SugarParameter ( paramterName , ExpressionTool . DynamicInvoke ( express ) ) ) ;
2017-07-12 00:15:14 +08:00
this . Context . Result . Append ( string . Format ( " {0} " , paramterName ) ) ;
2017-06-27 16:25:36 +08:00
this . Context . ParameterIndex + + ;
return ;
}
2017-07-16 04:35:42 +08:00
else if ( methodName = = "NewGuid" )
{
2017-07-12 00:15:14 +08:00
this . Context . Result . Append ( this . Context . DbMehtods . GuidNew ( ) ) ;
return ;
}
2021-04-24 03:20:01 +08:00
else if ( methodName = = "GetConfigValue" )
{
GetConfigValue ( express , parameter ) ;
return ;
}
2017-09-16 16:01:26 +08:00
else if ( IsSubMethod ( express , methodName ) )
{
2017-09-16 21:56:53 +08:00
//Check.Exception(!(parameter.BaseExpression is BinaryExpression), "Current expressions are not supported");
SubResolve subResolve = new SubResolve ( express , this . Context , parameter . OppsiteExpression ) ;
2017-09-16 16:01:26 +08:00
var appendSql = subResolve . GetSql ( ) ;
2019-05-15 18:11:44 +08:00
if ( this . Context . ResolveType . IsIn ( ResolveExpressType . SelectMultiple , ResolveExpressType . SelectSingle ) | | ( parameter . BaseParameter ! = null & & parameter . BaseParameter . CommonTempData ! = null & & parameter . BaseParameter . CommonTempData . Equals ( CommonTempDataType . Result ) ) )
2017-09-16 21:56:53 +08:00
{
parameter . BaseParameter . CommonTempData = appendSql ;
}
else
{
base . AppendValue ( parameter , isLeft , appendSql ) ;
}
2017-09-16 16:01:26 +08:00
return ;
}
2017-11-17 14:08:25 +08:00
else if ( IsIfElse ( express , methodName ) )
{
2017-11-10 12:35:41 +08:00
CaseWhenResolve caseResole = new CaseWhenResolve ( express , this . Context , parameter . OppsiteExpression ) ;
var appendSql = caseResole . GetSql ( ) ;
2019-05-15 18:11:44 +08:00
var isRoot = contextIndex = = 2 & & parameter . BaseExpression = = null ;
if ( isRoot | | ( parameter . BaseExpression ! = null & & ExpressionTool . IsLogicOperator ( parameter . BaseExpression ) ) )
{
appendSql = appendSql + "=1 " ;
2019-02-09 21:05:48 +08:00
}
2019-05-15 18:11:44 +08:00
if ( this . Context . ResolveType . IsIn ( ResolveExpressType . SelectMultiple , ResolveExpressType . SelectSingle , ResolveExpressType . Update ) )
2017-11-10 12:35:41 +08:00
{
parameter . BaseParameter . CommonTempData = appendSql ;
}
else
{
base . AppendValue ( parameter , isLeft , appendSql ) ;
}
2017-11-09 10:26:03 +08:00
return ;
}
2017-09-16 21:56:53 +08:00
if ( IsContainsArray ( express , methodName , isValidNativeMethod ) )
2017-07-16 04:35:42 +08:00
{
2017-06-14 01:08:12 +08:00
methodName = "ContainsArray" ;
isValidNativeMethod = true ;
}
2017-06-14 00:20:41 +08:00
if ( isValidNativeMethod )
{
2017-08-13 21:34:29 +08:00
NativeExtensionMethod ( parameter , express , isLeft , MethodMapping [ methodName ] , appendArgs ) ;
2017-06-14 00:20:41 +08:00
}
else
{
SqlFuncMethod ( parameter , express , isLeft ) ;
}
}
2021-04-24 03:20:01 +08:00
private void GetConfigValue ( MethodCallExpression express , ExpressionParameter parameter )
{
var exp = express . Arguments [ 0 ] ;
var name = Regex . Match ( express . Method . ToString ( ) , @"GetConfigValue\[(.+)\]" ) . Groups [ 1 ] . Value ;
string code = null ;
if ( express . Arguments . Count > 1 )
{
code = ExpressionTool . GetExpressionValue ( express . Arguments [ 1 ] ) + "" ;
}
2021-07-04 14:36:57 +08:00
var entityDb = SqlFuncExtendsion . TableInfos . FirstOrDefault ( y = > y . Type . Name = = name & & y . Code = = code ) ;
Check . Exception ( entityDb = = null , string . Format ( "GetConfigValue no configuration Entity={0} UniqueCode={1}" , name , code ) ) ;
var entity = new ConfigTableInfo ( )
{
Code = entityDb . Code ,
TableName = entityDb . TableName ,
Key = entityDb . Key ,
2021-07-04 15:05:19 +08:00
Parameter = new List < SugarParameter > ( ) ,
2021-07-04 14:36:57 +08:00
Type = entityDb . Type ,
Value = entityDb . Value ,
Where = entityDb . Where
} ;
2021-07-04 15:05:19 +08:00
if ( entityDb . Parameter ! = null & & entityDb . Parameter . Any ( ) )
{
foreach ( var item in entityDb . Parameter )
{
entity . Parameter . Add ( new SugarParameter ( "" , null ) {
DbType = item . DbType ,
Direction = item . Direction ,
IsArray = item . IsArray ,
IsJson = item . IsJson ,
IsNullable = item . IsNullable ,
IsRefCursor = item . IsRefCursor ,
ParameterName = item . ParameterName ,
Size = item . Size ,
SourceColumn = item . SourceColumn ,
SourceColumnNullMapping = item . SourceColumnNullMapping ,
SourceVersion = item . SourceVersion ,
TempDate = item . TempDate ,
TypeName = item . TypeName ,
Value = item . Value ,
_Size = item . _Size
} ) ;
}
}
2021-04-24 03:20:01 +08:00
string sql = " (SELECT {0} FROM {1} WHERE {2}={3}" ;
if ( ExpressionTool . IsUnConvertExpress ( exp ) )
{
exp = ( exp as UnaryExpression ) . Operand ;
}
var member = exp as MemberExpression ;
var it = member . Expression ;
var type = it . Type ;
var properyName = member . Member . Name ;
var eqName = string . Format ( "{0}.{1}" , this . Context . GetTranslationColumnName ( it . ToString ( ) ) , this . Context . GetDbColumnName ( type . Name , properyName ) ) ;
if ( this . Context . IsSingle )
{
this . Context . SingleTableNameSubqueryShortName = it . ToString ( ) ;
}
sql = string . Format ( sql , entity . Value , this . Context . GetTranslationColumnName ( entity . TableName ) , entity . Key , eqName ) ;
if ( entity . Parameter ! = null )
{
foreach ( var item in entity . Parameter )
{
var oldName = item . ParameterName ;
2021-06-29 17:42:53 +08:00
item . ParameterName = Regex . Split ( oldName , "_con_" ) . First ( ) + "_con_" + this . Context . ParameterIndex ;
2021-04-24 03:20:01 +08:00
entity . Where = entity . Where . Replace ( oldName , item . ParameterName ) ;
}
this . Context . ParameterIndex + + ;
this . Context . Parameters . AddRange ( entity . Parameter ) ;
}
if ( entity . Where . HasValue ( ) )
{
sql + = " AND " + entity . Where ;
}
sql + = " )" ;
if ( this . Context . ResolveType . IsIn ( ResolveExpressType . SelectMultiple , ResolveExpressType . SelectSingle , ResolveExpressType . Update ) )
{
parameter . BaseParameter . CommonTempData = sql ;
}
else
{
AppendMember ( parameter , parameter . IsLeft , sql ) ;
}
}
2019-05-15 18:11:44 +08:00
private bool IsValidNativeMethod ( MethodCallExpression express , string methodName )
2017-11-17 14:08:25 +08:00
{
return MethodMapping . ContainsKey ( methodName ) & & express . Method . DeclaringType . Namespace = = ( "System" ) ;
}
private bool IsExtMethod ( string methodName )
{
if ( this . Context . SqlFuncServices = = null ) return false ;
return this . Context . SqlFuncServices . Select ( it = > it . UniqueMethodName ) . Contains ( methodName ) ;
}
2017-11-09 10:26:03 +08:00
private bool IsIfElse ( MethodCallExpression express , string methodName )
{
2019-05-15 18:11:44 +08:00
if ( methodName = = "End" & & express . Object . Type = = typeof ( CaseWhen ) )
2017-11-09 10:26:03 +08:00
return true ;
else
return false ;
}
2019-02-09 18:49:32 +08:00
protected void SqlFuncMethod ( ExpressionParameter parameter , MethodCallExpression express , bool? isLeft )
2017-06-14 00:20:41 +08:00
{
2017-11-28 13:06:57 +08:00
if ( ! CheckMethod ( express ) )
{
CusMethod ( parameter , express , isLeft ) ;
2017-11-28 12:45:43 +08:00
}
2017-11-28 13:06:57 +08:00
else
2017-01-30 15:10:54 +08:00
{
2017-11-28 13:06:57 +08:00
var method = express . Method ;
string name = method . Name ;
var args = express . Arguments . Cast < Expression > ( ) . ToList ( ) ;
MethodCallExpressionModel model = new MethodCallExpressionModel ( ) ;
model . Args = new List < MethodCallExpressionArgs > ( ) ;
switch ( this . Context . ResolveType )
{
case ResolveExpressType . WhereSingle :
case ResolveExpressType . WhereMultiple :
Check . Exception ( name = = "GetSelfAndAutoFill" , "SqlFunc.GetSelfAndAutoFill can only be used in Select." ) ;
Where ( parameter , isLeft , name , args , model ) ;
break ;
case ResolveExpressType . SelectSingle :
case ResolveExpressType . SelectMultiple :
case ResolveExpressType . Update :
Select ( parameter , isLeft , name , args , model ) ;
break ;
case ResolveExpressType . FieldSingle :
case ResolveExpressType . FieldMultiple :
Field ( parameter , isLeft , name , args , model ) ;
break ;
default :
break ;
}
2017-01-30 15:10:54 +08:00
}
}
2017-11-28 13:06:57 +08:00
private void CusMethod ( ExpressionParameter parameter , MethodCallExpression express , bool? isLeft )
{
try
{
2022-04-13 18:25:00 +08:00
OneToManyNavgateExpression nav = new OneToManyNavgateExpression ( this . Context ? . SugarContext ? . Context , this ) ;
2022-04-13 17:40:15 +08:00
if ( nav . IsNavgate ( express ) )
{
var sql = nav . GetSql ( ) ;
2022-06-14 11:41:28 +08:00
SetNavigateResult ( ) ;
2022-04-13 17:40:15 +08:00
this . Context . SingleTableNameSubqueryShortName = nav . ShorName ;
base . AppendValue ( parameter , isLeft , sql ) ;
return ;
}
2022-05-02 21:04:36 +08:00
OneToManyNavgateExpressionN nav2 = new OneToManyNavgateExpressionN ( this . Context ? . SugarContext ? . Context , this ) ;
if ( nav2 . IsNavgate ( express ) )
{
var sql = nav2 . GetSql ( ) ;
2022-06-14 11:41:28 +08:00
SetNavigateResult ( ) ;
2022-05-02 21:04:36 +08:00
this . Context . SingleTableNameSubqueryShortName = nav2 . shorName ;
base . AppendValue ( parameter , isLeft , sql ) ;
return ;
}
2017-11-28 13:06:57 +08:00
var constValue = ExpressionTool . DynamicInvoke ( express ) ;
2021-01-17 02:35:33 +08:00
if ( constValue is MapperSql )
{
constValue = ( constValue as MapperSql ) . Sql ;
base . AppendValue ( parameter , isLeft , constValue ) ;
return ;
}
2017-11-28 13:06:57 +08:00
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 ) ;
}
}
2022-05-21 10:04:41 +08:00
catch ( Exception ex )
2017-11-28 13:06:57 +08:00
{
2022-05-21 10:04:41 +08:00
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 ) ) ;
}
2017-11-28 13:06:57 +08:00
}
}
2022-06-14 11:41:28 +08:00
2017-07-16 04:35:42 +08:00
private void NativeExtensionMethod ( ExpressionParameter parameter , MethodCallExpression express , bool? isLeft , string name , List < MethodCallExpressionArgs > appendArgs = null )
2017-06-14 00:20:41 +08:00
{
var method = express . Method ;
var args = express . Arguments . Cast < Expression > ( ) . ToList ( ) ;
MethodCallExpressionModel model = new MethodCallExpressionModel ( ) ;
2019-04-28 14:39:24 +08:00
model . Name = name ;
2017-06-14 00:20:41 +08:00
model . Args = new List < MethodCallExpressionArgs > ( ) ;
switch ( this . Context . ResolveType )
{
case ResolveExpressType . WhereSingle :
case ResolveExpressType . WhereMultiple :
if ( express . Object ! = null )
2017-06-14 01:00:16 +08:00
args . Insert ( 0 , express . Object ) ;
2017-07-16 04:35:42 +08:00
Where ( parameter , isLeft , name , args , model , appendArgs ) ;
2017-06-14 00:20:41 +08:00
break ;
case ResolveExpressType . SelectSingle :
case ResolveExpressType . SelectMultiple :
case ResolveExpressType . Update :
if ( express . Object ! = null )
args . Insert ( 0 , express . Object ) ;
2017-07-16 04:35:42 +08:00
Select ( parameter , isLeft , name , args , model , appendArgs ) ;
2017-06-14 00:20:41 +08:00
break ;
case ResolveExpressType . FieldSingle :
case ResolveExpressType . FieldMultiple :
2022-06-11 14:56:49 +08:00
if ( express . Method . Name = = "ToString" & & express . Object ! = null & & express . Object ? . Type = = UtilConstants . DateType )
2021-09-16 14:44:39 +08:00
{
2022-06-11 14:56:49 +08:00
var format = ( args [ 0 ] as ConstantExpression ) . Value + "" ;
2021-09-16 14:44:39 +08:00
var value = GetNewExpressionValue ( express . Object ) ;
var dateString = GeDateFormat ( format , value ) ;
base . AppendValue ( parameter , isLeft , dateString ) ;
}
2022-06-11 14:56:49 +08:00
else
{
var value = GetNewExpressionValue ( express , this . Context . IsJoin ? ResolveExpressType . WhereMultiple : ResolveExpressType . WhereSingle ) ;
base . AppendValue ( parameter , isLeft , value ) ;
}
2021-09-16 14:44:39 +08:00
break ;
2017-06-14 00:20:41 +08:00
default :
break ;
}
}
2019-02-09 18:49:32 +08:00
protected void Field ( ExpressionParameter parameter , bool? isLeft , string name , IEnumerable < Expression > args , MethodCallExpressionModel model , List < MethodCallExpressionArgs > appendArgs = null )
2017-08-14 01:01:23 +08:00
{
if ( this . Context . ResolveType = = ResolveExpressType . FieldSingle )
{
this . Context . ResolveType = ResolveExpressType . WhereSingle ;
}
2017-09-16 16:01:26 +08:00
else
{
2017-08-14 01:01:23 +08:00
this . Context . ResolveType = ResolveExpressType . WhereMultiple ;
}
Where ( parameter , isLeft , name , args , model ) ;
}
2019-02-09 18:49:32 +08:00
protected void Select ( ExpressionParameter parameter , bool? isLeft , string name , IEnumerable < Expression > args , MethodCallExpressionModel model , List < MethodCallExpressionArgs > appendArgs = null )
2017-04-30 16:11:51 +08:00
{
2021-04-24 12:36:39 +08:00
if ( name . IsIn ( "GetSelfAndAutoFill" , "SelectAll" ) )
2017-04-30 16:11:51 +08:00
{
2017-07-17 12:56:21 +08:00
var memberValue = ( args . First ( ) as MemberExpression ) . Expression . ToString ( ) ;
2021-11-23 22:33:49 +08:00
var data = new MethodCallExpressionArgs ( ) { MemberValue = memberValue , IsMember = true , MemberName = memberValue } ;
model . Args . Add ( data ) ;
if ( args . Count ( ) = = 2 )
{
data . MemberName = ( args . Last ( ) ) . ToString ( ) ;
data . MemberValue = "." ;
}
2017-07-17 12:56:21 +08:00
}
else
{
foreach ( var item in args )
2017-04-30 16:11:51 +08:00
{
2017-08-13 21:34:29 +08:00
AppendItem ( parameter , name , args , model , item ) ;
2017-04-30 16:11:51 +08:00
}
2017-07-17 12:56:21 +08:00
if ( appendArgs ! = null )
2017-04-30 16:11:51 +08:00
{
2017-07-17 12:56:21 +08:00
model . Args . AddRange ( appendArgs ) ;
2017-04-30 16:11:51 +08:00
}
}
2017-09-16 16:01:26 +08:00
if ( parameter . BaseParameter . BaseParameter . BaseParameter = = null )
2017-09-11 13:24:48 +08:00
{
2018-11-26 23:29:00 +08:00
this . Context . Result . Append ( GetMethodValue ( name , model ) ) ;
2017-09-11 13:24:48 +08:00
}
else
{
2018-11-26 23:29:00 +08:00
parameter . BaseParameter . CommonTempData = GetMethodValue ( name , model ) ;
2017-09-11 13:24:48 +08:00
}
2017-04-30 16:11:51 +08:00
}
2019-02-09 18:49:32 +08:00
protected void Where ( ExpressionParameter parameter , bool? isLeft , string name , IEnumerable < Expression > args , MethodCallExpressionModel model , List < MethodCallExpressionArgs > appendArgs = null )
2017-04-30 16:11:51 +08:00
{
foreach ( var item in args )
{
2017-12-19 16:20:35 +08:00
var expItem = item ;
2019-05-15 18:11:44 +08:00
if ( item is UnaryExpression )
{
2017-12-19 16:20:35 +08:00
expItem = ( item as UnaryExpression ) . Operand ;
}
AppendItem ( parameter , name , args , model , expItem ) ;
2017-04-30 16:11:51 +08:00
}
2017-07-16 04:35:42 +08:00
if ( appendArgs ! = null )
{
model . Args . AddRange ( appendArgs ) ;
}
2018-11-26 23:29:00 +08:00
var methodValue = GetMethodValue ( name , model ) ;
2019-05-15 18:11:44 +08:00
if ( parameter . BaseExpression is BinaryExpression & & parameter . OppsiteExpression . Type = = UtilConstants . BoolType & & name = = "HasValue" & & ! ( parameter . OppsiteExpression is BinaryExpression ) & & ! ( parameter . OppsiteExpression is MethodCallExpression & & parameter . OppsiteExpression . Type = = UtilConstants . BoolType ) )
2019-04-15 17:33:33 +08:00
{
methodValue = packIfElse ( methodValue ) ;
}
2019-05-15 18:11:44 +08:00
if ( parameter . OppsiteExpression ! = null & & name = = "IsNullOrEmpty" & & parameter . OppsiteExpression . Type = = UtilConstants . BoolType & & parameter . OppsiteExpression is ConstantExpression )
2019-04-15 17:33:33 +08:00
{
methodValue = packIfElse ( methodValue ) ;
2017-11-13 12:50:55 +08:00
}
2019-02-09 20:53:44 +08:00
var isRoot = contextIndex = = 2 ;
2019-05-15 18:11:44 +08:00
if ( isRoot & & parameter . BaseExpression = = null & & this . Context . ResolveType . IsIn ( ResolveExpressType . WhereMultiple , ResolveExpressType . WhereSingle ) & & ( parameter . CurrentExpression is MethodCallExpression ) & & ( ( parameter . CurrentExpression as MethodCallExpression ) . Method . Name . IsIn ( "ToBool" , "ToBoolean" ) ) )
2019-02-06 19:53:24 +08:00
{
methodValue = methodValue + "=1 " ;
2019-05-15 18:11:44 +08:00
;
}
if ( isRoot & & parameter . BaseExpression = = null & & this . Context . ResolveType . IsIn ( ResolveExpressType . WhereMultiple , ResolveExpressType . WhereSingle ) & & ( parameter . CurrentExpression is ConditionalExpression ) & & ( ( parameter . CurrentExpression as ConditionalExpression ) . Type = = UtilConstants . BoolType ) )
2019-02-09 20:53:44 +08:00
{
2022-07-06 05:04:37 +08:00
var isContainsTrue = MethodValueIsTrue ( methodValue ) ;
if ( isContainsTrue )
{
methodValue = methodValue + "=true " ;
}
else
{
methodValue = methodValue + "=1 " ;
}
2019-02-09 20:53:44 +08:00
}
2019-05-15 18:11:44 +08:00
if ( isRoot & & parameter . BaseExpression = = null & & this . Context . ResolveType . IsIn ( ResolveExpressType . WhereMultiple , ResolveExpressType . WhereSingle ) & & ( parameter . CurrentExpression is MethodCallExpression ) & & ( ( parameter . CurrentExpression as MethodCallExpression ) . Method . Name . IsIn ( "IIF" ) ) & & ( parameter . CurrentExpression as MethodCallExpression ) . Method . ReturnType = = UtilConstants . BoolType )
2019-02-09 20:53:44 +08:00
{
methodValue = methodValue + "=1 " ;
}
2019-05-15 18:11:44 +08:00
if ( parameter . BaseExpression ! = null & & ExpressionTool . IsLogicOperator ( parameter . BaseExpression ) & & this . Context . ResolveType . IsIn ( ResolveExpressType . WhereMultiple , ResolveExpressType . WhereSingle ) & & ( parameter . CurrentExpression is ConditionalExpression ) & & ( ( parameter . CurrentExpression as ConditionalExpression ) . Type = = UtilConstants . BoolType ) )
2019-02-09 21:21:44 +08:00
{
methodValue = methodValue + "=1 " ;
}
if ( parameter . BaseExpression ! = null & & ExpressionTool . IsLogicOperator ( parameter . BaseExpression ) & & this . Context . ResolveType . IsIn ( ResolveExpressType . WhereMultiple , ResolveExpressType . WhereSingle ) & & ( parameter . CurrentExpression is MethodCallExpression ) & & ( ( parameter . CurrentExpression as MethodCallExpression ) . Method . Name . IsIn ( "IIF" ) ) & & ( parameter . CurrentExpression as MethodCallExpression ) . Method . ReturnType = = UtilConstants . BoolType )
{
methodValue = methodValue + "=1 " ;
}
2019-05-15 18:11:44 +08:00
if ( parameter . BaseExpression ! = null & & ExpressionTool . IsLogicOperator ( parameter . BaseExpression ) & & this . Context . ResolveType . IsIn ( ResolveExpressType . WhereMultiple , ResolveExpressType . WhereSingle ) & & ( parameter . CurrentExpression is MethodCallExpression ) & & ( ( parameter . CurrentExpression as MethodCallExpression ) . Method . Name . IsIn ( "ToBool" , "ToBoolean" ) ) )
2019-02-09 21:24:31 +08:00
{
methodValue = methodValue + "=1 " ;
}
2017-04-30 16:11:51 +08:00
base . AppendValue ( parameter , isLeft , methodValue ) ;
}
2017-08-13 21:34:29 +08:00
2022-07-06 05:04:37 +08:00
private static bool MethodValueIsTrue ( object methodValue )
{
return methodValue ! = null & & methodValue . ToString ( ) . Contains ( "THEN true ELSE false END" ) ;
}
2019-04-15 17:33:33 +08:00
private object packIfElse ( object methodValue )
{
methodValue = this . Context . DbMehtods . CaseWhen ( new List < KeyValuePair < string , string > > ( ) {
new KeyValuePair < string , string > ( "IF" , methodValue . ObjToString ( ) ) ,
new KeyValuePair < string , string > ( "Return" , "1" ) ,
new KeyValuePair < string , string > ( "End" , "0" )
} ) ;
return methodValue ;
}
2017-08-13 21:34:29 +08:00
private void AppendItem ( ExpressionParameter parameter , string name , IEnumerable < Expression > args , MethodCallExpressionModel model , Expression item )
{
2019-04-26 19:53:51 +08:00
if ( ExpressionTool . IsUnConvertExpress ( item ) )
{
item = ( item as UnaryExpression ) . Operand ;
}
2017-08-13 21:34:29 +08:00
var isBinaryExpression = item is BinaryExpression | | item is MethodCallExpression ;
2017-08-14 00:01:01 +08:00
var isConst = item is ConstantExpression ;
2017-09-16 16:01:26 +08:00
var isIIF = name = = "IIF" ;
2021-12-25 16:00:01 +08:00
var isSubIIF = ( isIIF & & item . ToString ( ) . StartsWith ( "IIF" ) ) ;
2017-08-25 22:22:12 +08:00
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 ;
2017-08-14 00:01:01 +08:00
var isFirst = item = = args . First ( ) ;
2021-12-25 17:00:28 +08:00
var isBoolValue = item . Type = = UtilConstants . BoolType & & item . ToString ( ) . StartsWith ( "value(" ) ;
2017-08-14 00:39:25 +08:00
if ( isFirst & & isIIF & & isConst )
2017-08-14 00:01:01 +08:00
{
var value = ( item as ConstantExpression ) . Value . ObjToBool ( ) ? this . Context . DbMehtods . True ( ) : this . Context . DbMehtods . False ( ) ;
var methodCallExpressionArgs = new MethodCallExpressionArgs ( )
{
2017-08-14 00:39:25 +08:00
IsMember = true ,
2017-08-14 00:01:01 +08:00
MemberName = value ,
2017-08-14 00:39:25 +08:00
MemberValue = value
2017-08-14 00:01:01 +08:00
} ;
model . Args . Add ( methodCallExpressionArgs ) ;
}
else if ( isIFFUnary & & ! isFirst )
2017-08-13 21:34:29 +08:00
{
AppendModelByIIFMember ( parameter , model , ( item as UnaryExpression ) . Operand ) ;
}
2017-08-14 00:01:01 +08:00
else if ( isIFFBoolMember & & ! isFirst )
2017-08-13 21:34:29 +08:00
{
AppendModelByIIFMember ( parameter , model , item ) ;
}
2017-08-14 00:01:01 +08:00
else if ( isIFFBoolBinary & & ! isFirst )
2017-08-13 21:34:29 +08:00
{
2022-07-06 05:04:37 +08:00
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 < MethodCallExpressionArgs > ( )
{
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 ) ;
}
2017-08-13 21:34:29 +08:00
}
2017-09-16 16:01:26 +08:00
else if ( isIFFBoolMethod & & ! isFirst )
{
2017-08-14 00:39:25 +08:00
AppendModelByIIFMethod ( parameter , model , item ) ;
}
2017-08-13 21:34:29 +08:00
else if ( isBinaryExpression )
{
model . Args . Add ( GetMethodCallArgs ( parameter , item ) ) ;
}
2021-12-25 17:00:28 +08:00
else if ( isSubIIF )
2021-12-25 16:00:01 +08:00
{
model . Args . Add ( GetMethodCallArgs ( parameter , item ) ) ;
}
2021-12-25 17:00:28 +08:00
else if ( isBoolValue & & ! isIIF & & item is MemberExpression )
{
model . Args . Add ( GetMethodCallArgs ( parameter , ( item as MemberExpression ) . Expression ) ) ;
}
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 ) ;
}
2017-08-13 21:34:29 +08:00
else
{
AppendModel ( parameter , model , item ) ;
}
}
2019-04-26 19:53:51 +08:00
2017-08-13 21:34:29 +08:00
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 )
{
2017-08-14 00:39:25 +08:00
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 ;
2017-09-16 16:01:26 +08:00
if ( methodExpression . Method . Name . IsIn ( "ToBool" , "ToBoolean" , "IIF" ) )
2017-08-13 21:34:29 +08:00
{
2017-08-14 00:39:25 +08:00
model . Args . Add ( base . GetMethodCallArgs ( parameter , item ) ) ;
2017-08-13 21:34:29 +08:00
}
2017-08-14 00:39:25 +08:00
else
2017-08-13 21:34:29 +08:00
{
2017-08-14 00:39:25 +08:00
Check . Exception ( true , "The SqlFunc.IIF(arg1,arg2,arg3) , {0} argument do not support " , item . ToString ( ) ) ;
2017-08-13 21:34:29 +08:00
}
}
private void AppendModel ( ExpressionParameter parameter , MethodCallExpressionModel model , Expression item )
2017-06-12 17:47:25 +08:00
{
parameter . CommonTempData = CommonTempDataType . Result ;
base . Expression = item ;
2019-04-15 12:32:02 +08:00
if ( item . Type = = UtilConstants . DateType & & parameter . CommonTempData . ObjToString ( ) = = CommonTempDataType . Result . ToString ( ) & & item . ToString ( ) = = "DateTime.Now.Date" )
{
parameter . CommonTempData = DateTime . Now . Date ;
}
2022-04-08 21:09:34 +08:00
else if ( item is ConditionalExpression )
{
parameter . CommonTempData = GetNewExpressionValue ( item ) ;
}
else if ( IsNot ( item ) )
2022-04-08 15:31:05 +08:00
{
parameter . CommonTempData = GetNewExpressionValue ( item ) ;
}
2019-05-28 18:46:44 +08:00
else if ( IsDateDate ( item ) )
{
parameter . CommonTempData = GetNewExpressionValue ( item ) ;
}
2019-06-02 18:32:57 +08:00
else if ( IsDateValue ( item ) )
{
parameter . CommonTempData = GetNewExpressionValue ( item ) ;
}
2019-05-15 18:11:44 +08:00
else if ( model . Name = = "ToString" & & item is ConstantExpression & & ( item as ConstantExpression ) . Type . IsEnum ( ) )
2019-04-28 14:39:24 +08:00
{
parameter . CommonTempData = item . ToString ( ) ;
}
2022-03-24 11:02:20 +08:00
else if ( IsDateItemValue ( item ) )
{
parameter . CommonTempData = GetNewExpressionValue ( item ) ;
}
2019-04-28 14:39:24 +08:00
else
{
2019-04-15 12:32:02 +08:00
base . Start ( ) ;
}
2017-06-12 17:47:25 +08:00
var methodCallExpressionArgs = new MethodCallExpressionArgs ( )
{
2017-11-07 16:13:22 +08:00
IsMember = parameter . ChildExpression is MemberExpression & & ! ExpressionTool . IsConstExpression ( parameter . ChildExpression as MemberExpression ) ,
2017-06-12 17:47:25 +08:00
MemberName = parameter . CommonTempData
} ;
2022-04-18 23:03:26 +08:00
if ( methodCallExpressionArgs . MemberName is MapperSql )
{
methodCallExpressionArgs . MemberName = ( methodCallExpressionArgs . MemberName as MapperSql ) . Sql ;
}
2017-06-12 17:47:25 +08:00
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 ;
}
}
2022-04-08 21:09:34 +08:00
if ( IsDateDate ( item ) | | IsDateValue ( item ) | | IsDateItemValue ( item ) | | item is ConditionalExpression | | IsNot ( item ) )
2019-05-28 18:46:44 +08:00
{
methodCallExpressionArgs . IsMember = true ;
}
2019-05-15 18:11:44 +08:00
if ( methodCallExpressionArgs . IsMember = = false & & ( item is MethodCallExpression & & item . ToString ( ) = = "GetDate()" ) | | ( item is UnaryExpression & & ( ( UnaryExpression ) item ) . Operand . ToString ( ) = = "GetDate()" ) )
{
2019-04-15 21:27:57 +08:00
var parameterName = this . Context . SqlParameterKeyWord + ExpressionConst . MethodConst + this . Context . ParameterIndex ;
this . Context . ParameterIndex + + ;
methodCallExpressionArgs . MemberName = value ;
methodCallExpressionArgs . MemberValue = null ;
}
else if ( methodCallExpressionArgs . IsMember = = false )
2017-06-12 17:47:25 +08:00
{
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 ) ;
2017-06-15 07:43:58 +08:00
parameter . ChildExpression = null ;
2017-06-12 17:47:25 +08:00
}
2017-01-31 20:13:22 +08:00
2022-04-08 21:09:34 +08:00
private static bool IsNot ( Expression item )
{
return item is UnaryExpression & & ( item as UnaryExpression ) . NodeType = = ExpressionType . Not ;
}
2022-03-24 11:02:20 +08:00
private bool IsDateItemValue ( Expression item )
{
var result = false ;
if ( item is MemberExpression )
{
var memberExp = item as MemberExpression ;
if ( memberExp ! = null & & memberExp . Expression ! = null & & memberExp . Expression . Type = = UtilConstants . DateType )
{
foreach ( var dateType in UtilMethods . EnumToDictionary < DateType > ( ) )
{
if ( memberExp . Member . Name . EqualCase ( dateType . Key ) )
{
result = true ;
break ;
}
else if ( memberExp . Member . Name = = "DayOfWeek" )
{
result = true ;
break ;
}
}
}
}
return result ;
}
2019-05-28 18:46:44 +08:00
private static bool IsDateDate ( Expression item )
{
2020-10-27 15:21:26 +08:00
return item . Type = = UtilConstants . DateType & & item is MemberExpression & & ( item as MemberExpression ) . Member . Name = = "Date" & & item . ToString ( ) ! = "DateTime.Now.Date" ;
2019-05-28 18:46:44 +08:00
}
2019-06-02 18:32:57 +08:00
private static bool IsDateValue ( Expression item )
{
2020-10-27 15:21:26 +08:00
return item . Type = = UtilConstants . IntType & &
item is MemberExpression & &
( item as MemberExpression ) . Expression ! = null & &
( item as MemberExpression ) . Expression . Type = = UtilConstants . DateType & &
( item as MemberExpression ) . Expression is MemberExpression & &
( ( item as MemberExpression ) . Expression as MemberExpression ) . Member . Name = = "Value" ;
2019-06-02 18:32:57 +08:00
}
2019-05-28 18:46:44 +08:00
2018-11-26 23:29:00 +08:00
private object GetMethodValue ( string name , MethodCallExpressionModel model )
2017-01-30 15:10:54 +08:00
{
2017-11-17 14:08:25 +08:00
if ( IsExtMethod ( name ) )
{
2020-10-27 15:21:26 +08:00
model . Expression = this . Expression ;
model . BaseExpression = this . BaseParameter . CurrentExpression ;
2017-11-17 14:08:25 +08:00
DbType type = DbType . SqlServer ;
if ( this . Context is SqlServerExpressionContext )
type = DbType . SqlServer ;
else if ( this . Context is MySqlExpressionContext )
type = DbType . MySql ;
else if ( this . Context is SqliteExpressionContext )
type = DbType . Sqlite ;
2019-05-15 18:11:44 +08:00
else if ( this . Context is OracleExpressionContext )
2017-11-17 14:08:25 +08:00
type = DbType . Oracle ;
2021-06-19 12:52:23 +08:00
else if ( this . Context is PostgreSQLExpressionContext )
type = DbType . PostgreSQL ;
2022-02-01 13:59:32 +08:00
else if ( this . Context . GetType ( ) . Name . StartsWith ( "MySql" ) )
{
type = DbType . MySql ;
}
2019-05-15 18:11:44 +08:00
return this . Context . SqlFuncServices . First ( it = > it . UniqueMethodName = = name ) . MethodValue ( model , type , this . Context ) ;
2017-11-17 14:08:25 +08:00
}
else
{
2020-10-27 15:21:26 +08:00
if ( name = = "Parse" & & TempParseType . IsIn ( UtilConstants . GuidType ) & & model . Args ! = null & & model . Args . Count ( ) > 1 )
2019-02-06 17:53:40 +08:00
{
name = "Equals" ;
}
2019-05-15 18:11:44 +08:00
else if ( name = = "Parse" )
2019-02-06 17:53:40 +08:00
{
2019-05-15 18:11:44 +08:00
name = "To" + TempParseType . Name ;
2019-02-06 17:53:40 +08:00
}
2020-12-04 19:52:19 +08:00
else if ( name = = "IsNullOrWhiteSpace" )
{
name = "IsNullOrEmpty" ;
}
2017-11-17 14:08:25 +08:00
switch ( name )
{
case "IIF" :
return this . Context . DbMehtods . IIF ( model ) ;
case "HasNumber" :
return this . Context . DbMehtods . HasNumber ( model ) ;
case "HasValue" :
return this . Context . DbMehtods . HasValue ( model ) ;
case "IsNullOrEmpty" :
return this . Context . DbMehtods . IsNullOrEmpty ( model ) ;
case "ToLower" :
return this . Context . DbMehtods . ToLower ( model ) ;
case "ToUpper" :
return this . Context . DbMehtods . ToUpper ( model ) ;
case "Trim" :
return this . Context . DbMehtods . Trim ( model ) ;
case "Contains" :
return this . Context . DbMehtods . Contains ( model ) ;
case "ContainsArray" :
2019-06-01 12:20:22 +08:00
if ( model . Args [ 0 ] . MemberValue = = null )
{
var first = this . Context . Parameters . FirstOrDefault ( it = > it . ParameterName = = model . Args [ 0 ] . MemberName . ObjToString ( ) ) ;
if ( first . HasValue ( ) )
{
model . Args [ 0 ] . MemberValue = first . Value ;
}
}
2021-12-30 16:42:55 +08:00
if ( this . Context . TableEnumIsString = = true )
{
List < string > enumStringList = new List < string > ( ) ;
foreach ( var inItem in ( model . Args [ 0 ] . MemberValue as IEnumerable ) )
{
if ( inItem ! = null )
{
if ( UtilMethods . GetUnderType ( inItem . GetType ( ) ) . IsEnum ( ) )
{
enumStringList . Add ( inItem . ToString ( ) ) ;
}
}
}
if ( enumStringList . Any ( ) )
{
model . Args [ 0 ] . MemberValue = enumStringList ;
}
}
2017-11-17 14:08:25 +08:00
var caResult = this . Context . DbMehtods . ContainsArray ( model ) ;
this . Context . Parameters . RemoveAll ( it = > it . ParameterName = = model . Args [ 0 ] . MemberName . ObjToString ( ) ) ;
return caResult ;
2019-06-09 20:51:57 +08:00
case "ContainsArrayUseSqlParameters" :
if ( model . Args [ 0 ] . MemberValue = = null )
{
var first = this . Context . Parameters . FirstOrDefault ( it = > it . ParameterName = = model . Args [ 0 ] . MemberName . ObjToString ( ) ) ;
if ( first . HasValue ( ) )
{
model . Args [ 0 ] . MemberValue = first . Value ;
}
}
2020-10-27 15:21:26 +08:00
model . Data = this . Context . SqlParameterKeyWord + "INP_" + this . Context . ParameterIndex ;
2019-06-09 20:51:57 +08:00
this . Context . ParameterIndex + + ;
if ( model . Args [ 0 ] . MemberValue . HasValue ( ) )
{
var inValueIEnumerable = ( IEnumerable ) model . Args [ 0 ] . MemberValue ;
int i = 0 ;
2020-10-27 15:21:26 +08:00
foreach ( var item in inValueIEnumerable )
2019-06-09 20:51:57 +08:00
{
2020-10-27 15:21:26 +08:00
this . Context . Parameters . Add ( new SugarParameter ( model . Data + "_" + i , item ) ) ;
2019-06-09 20:51:57 +08:00
i + + ;
}
}
var caResult2 = this . Context . DbMehtods . ContainsArrayUseSqlParameters ( model ) ;
this . Context . Parameters . RemoveAll ( it = > it . ParameterName = = model . Args [ 0 ] . MemberName . ObjToString ( ) ) ;
return caResult2 ;
2017-11-17 14:08:25 +08:00
case "Equals" :
return this . Context . DbMehtods . Equals ( model ) ;
2020-10-29 17:15:23 +08:00
case "EqualsNull" :
return this . Context . DbMehtods . EqualsNull ( model ) ;
2017-11-17 14:08:25 +08:00
case "DateIsSame" :
if ( model . Args . Count = = 2 )
return this . Context . DbMehtods . DateIsSameDay ( model ) ;
else
{
var dsResult = this . Context . DbMehtods . DateIsSameByType ( model ) ;
this . Context . Parameters . RemoveAll ( it = > it . ParameterName = = model . Args [ 2 ] . MemberName . ObjToString ( ) ) ;
return dsResult ;
}
case "DateAdd" :
if ( model . Args . Count = = 2 )
return this . Context . DbMehtods . DateAddDay ( model ) ;
else
{
var daResult = this . Context . DbMehtods . DateAddByType ( model ) ;
this . Context . Parameters . RemoveAll ( it = > it . ParameterName = = model . Args [ 2 ] . MemberName . ObjToString ( ) ) ;
return daResult ;
}
case "DateValue" :
var dvResult = this . Context . DbMehtods . DateValue ( model ) ;
this . Context . Parameters . RemoveAll ( it = > it . ParameterName = = model . Args [ 1 ] . MemberName . ObjToString ( ) ) ;
return dvResult ;
case "Between" :
return this . Context . DbMehtods . Between ( model ) ;
case "StartsWith" :
return this . Context . DbMehtods . StartsWith ( model ) ;
case "EndsWith" :
return this . Context . DbMehtods . EndsWith ( model ) ;
case "ToInt32" :
return this . Context . DbMehtods . ToInt32 ( model ) ;
case "ToInt64" :
return this . Context . DbMehtods . ToInt64 ( model ) ;
case "ToDate" :
return this . Context . DbMehtods . ToDate ( model ) ;
2019-02-06 18:04:56 +08:00
case "ToDateTime" :
return this . Context . DbMehtods . ToDate ( model ) ;
2017-11-17 14:08:25 +08:00
case "ToTime" :
return this . Context . DbMehtods . ToTime ( model ) ;
case "ToString" :
2021-12-22 13:13:51 +08:00
if ( model . Args . Count > 1 )
2019-05-15 18:11:44 +08:00
{
return GeDateFormat ( model . Args . Last ( ) . MemberValue . ObjToString ( ) , model . Args . First ( ) . MemberName . ObjToString ( ) ) ;
}
2021-12-22 13:13:51 +08:00
//Check.Exception(model.Args.Count > 1, "ToString (Format) is not supported, Use ToString().If time formatting can be used it.Date.Year+\"-\"+it.Data.Month+\"-\"+it.Date.Day ");
2017-11-17 14:08:25 +08:00
return this . Context . DbMehtods . ToString ( model ) ;
2020-05-25 18:27:16 +08:00
case "ToVarchar" :
return this . Context . DbMehtods . ToVarchar ( model ) ;
2017-11-17 14:08:25 +08:00
case "ToDecimal" :
return this . Context . DbMehtods . ToDecimal ( model ) ;
case "ToGuid" :
return this . Context . DbMehtods . ToGuid ( model ) ;
case "ToDouble" :
return this . Context . DbMehtods . ToDouble ( model ) ;
case "ToBool" :
return this . Context . DbMehtods . ToBool ( model ) ;
2019-02-06 18:04:56 +08:00
case "ToBoolean" :
return this . Context . DbMehtods . ToBool ( model ) ;
2017-11-17 14:08:25 +08:00
case "Substring" :
return this . Context . DbMehtods . Substring ( model ) ;
case "Replace" :
return this . Context . DbMehtods . Replace ( model ) ;
case "Length" :
return this . Context . DbMehtods . Length ( model ) ;
case "AggregateSum" :
return this . Context . DbMehtods . AggregateSum ( model ) ;
case "AggregateAvg" :
return this . Context . DbMehtods . AggregateAvg ( model ) ;
case "AggregateMin" :
return this . Context . DbMehtods . AggregateMin ( model ) ;
case "AggregateMax" :
return this . Context . DbMehtods . AggregateMax ( model ) ;
case "AggregateCount" :
return this . Context . DbMehtods . AggregateCount ( model ) ;
2019-05-25 07:29:17 +08:00
case "AggregateDistinctCount" :
return this . Context . DbMehtods . AggregateDistinctCount ( model ) ;
2017-11-17 14:08:25 +08:00
case "MappingColumn" :
var mappingColumnResult = this . Context . DbMehtods . MappingColumn ( model ) ;
var isValid = model . Args [ 0 ] . IsMember & & model . Args [ 1 ] . IsMember = = false ;
2021-01-07 11:29:43 +08:00
//Check.Exception(!isValid, "SqlFunc.MappingColumn parameters error, The property name on the left, string value on the right");
2017-11-17 14:08:25 +08:00
this . Context . Parameters . RemoveAll ( it = > it . ParameterName = = model . Args [ 1 ] . MemberName . ObjToString ( ) ) ;
2021-07-31 18:11:54 +08:00
if ( mappingColumnResult = = "" )
{
return model . Args [ 1 ] . MemberName . ObjToString ( ) . TrimStart ( '\'' ) . TrimEnd ( '\'' ) ;
}
2017-11-17 14:08:25 +08:00
return mappingColumnResult ;
case "IsNull" :
return this . Context . DbMehtods . IsNull ( model ) ;
case "MergeString" :
return this . Context . DbMehtods . MergeString ( model . Args . Select ( it = > it . MemberName . ObjToString ( ) ) . ToArray ( ) ) ;
2021-04-24 12:36:39 +08:00
case "SelectAll" :
2017-11-17 14:08:25 +08:00
case "GetSelfAndAutoFill" :
this . Context . Parameters . RemoveAll ( it = > it . ParameterName = = model . Args [ 0 ] . MemberName . ObjToString ( ) ) ;
2021-11-23 22:33:49 +08:00
var result1 = this . Context . DbMehtods . GetSelfAndAutoFill ( model . Args [ 0 ] . MemberValue . ObjToString ( ) , this . Context . IsSingle ) ;
if ( ( model . Args [ 0 ] . MemberValue + "" ) = = "." & & this . Context . IsSingle )
{
result1 = this . Context . GetTranslationTableName ( model . Args [ 0 ] . MemberName + "" , false ) + ".*/**/" + result1 ;
}
return result1 ;
2017-11-17 14:08:25 +08:00
case "GetDate" :
return this . Context . DbMehtods . GetDate ( ) ;
2018-09-29 14:44:05 +08:00
case "GetRandom" :
return this . Context . DbMehtods . GetRandom ( ) ;
2019-05-14 13:11:07 +08:00
case "CharIndex" :
return this . Context . DbMehtods . CharIndex ( model ) ;
2020-11-07 12:54:42 +08:00
case "BitwiseAnd" :
return this . Context . DbMehtods . BitwiseAnd ( model ) ;
case "BitwiseInclusiveOR" :
return this . Context . DbMehtods . BitwiseInclusiveOR ( model ) ;
2020-11-22 14:31:22 +08:00
case "ToDateShort" :
return this . Context . DbMehtods . ToDateShort ( model ) ;
2021-02-04 17:18:21 +08:00
case "Oracle_ToChar" :
return this . Context . DbMehtods . Oracle_ToChar ( model ) ;
case "Oracle_ToDate" :
return this . Context . DbMehtods . Oracle_ToDate ( model ) ;
case "SqlServer_DateDiff" :
return this . Context . DbMehtods . SqlServer_DateDiff ( model ) ;
2021-07-31 18:11:54 +08:00
case "Format" :
var xx = base . BaseParameter ;
var result = this . Context . DbMehtods . Format ( model ) ;
this . Context . Parameters . RemoveAll ( it = > model . Args . Select ( x = > x . MemberName . ObjToString ( ) ) . Contains ( it . ParameterName ) ) ;
return result ;
2021-09-04 09:26:02 +08:00
case "Abs" :
return this . Context . DbMehtods . Abs ( model ) ;
case "Round" :
return this . Context . DbMehtods . Round ( model ) ;
2022-03-22 20:09:21 +08:00
case "DateDiff" :
return this . Context . DbMehtods . DateDiff ( model ) ;
case "GreaterThan" :
return this . Context . DbMehtods . GreaterThan ( model ) ;
case "GreaterThanOrEqual" :
return this . Context . DbMehtods . GreaterThanOrEqual ( model ) ;
case "LessThan" :
return this . Context . DbMehtods . LessThan ( model ) ;
case "LessThanOrEqual" :
return this . Context . DbMehtods . LessThanOrEqual ( model ) ;
2022-04-09 17:02:31 +08:00
case "Asc" :
return this . Context . DbMehtods . Asc ( model ) ;
case "Desc" :
return this . Context . DbMehtods . Desc ( model ) ;
2022-07-09 03:16:12 +08:00
case "Stuff" :
return this . Context . DbMehtods . Stuff ( model ) ;
2017-11-17 14:08:25 +08:00
default :
break ;
}
2017-01-30 15:10:54 +08:00
}
return null ;
}
2017-11-07 16:13:22 +08:00
private bool IsContainsArray ( MethodCallExpression express , string methodName , bool isValidNativeMethod )
2017-09-16 21:56:53 +08:00
{
return ! isValidNativeMethod & & express . Method . DeclaringType . Namespace . IsIn ( "System.Linq" , "System.Collections.Generic" ) & & methodName = = "Contains" ;
}
2017-09-16 16:01:26 +08:00
2017-11-07 16:13:22 +08:00
private bool IsSubMethod ( MethodCallExpression express , string methodName )
2017-09-16 16:01:26 +08:00
{
2021-12-24 21:29:56 +08:00
return SubTools . SubItemsConst . Any ( it = > it . Name = = methodName ) & & express . Object ! = null & & ( express . Object . Type . Name . StartsWith ( "Subqueryable`" ) ) ;
2017-09-16 16:01:26 +08:00
}
2017-11-28 12:45:43 +08:00
private bool CheckMethod ( MethodCallExpression expression )
2017-01-30 15:10:54 +08:00
{
2021-04-24 12:36:39 +08:00
if ( expression . Method . Name = = "SelectAll" )
{
return true ;
}
2021-07-31 18:11:54 +08:00
if ( expression . Method . Name = = "Format" & & expression . Method . DeclaringType = = UtilConstants . StringType )
{
return true ;
}
2017-11-28 12:45:43 +08:00
if ( IsExtMethod ( expression . Method . Name ) )
return true ;
2019-05-15 18:11:44 +08:00
if ( IsParseMethod ( expression ) )
2019-02-06 17:53:40 +08:00
return true ;
2019-05-15 18:11:44 +08:00
if ( expression . Method . Name = = "IsNullOrEmpty" & & expression . Method . DeclaringType = = UtilConstants . StringType )
2019-02-06 21:44:51 +08:00
{
return true ;
}
2020-12-04 19:52:19 +08:00
if ( expression . Method . Name = = "IsNullOrWhiteSpace" & & expression . Method . DeclaringType = = UtilConstants . StringType )
{
return true ;
}
2017-11-28 12:45:43 +08:00
if ( expression . Method . ReflectedType ( ) . FullName ! = ExpressionConst . SqlFuncFullName )
return false ;
else
return true ;
2017-01-07 21:54:51 +08:00
}
2019-02-06 17:53:40 +08:00
private Type TempParseType ;
2019-05-15 18:11:44 +08:00
public bool IsParseMethod ( MethodCallExpression expression )
2019-02-06 17:53:40 +08:00
{
2019-05-15 18:11:44 +08:00
if ( expression . Method . Name = = "Parse" & & expression . Method . DeclaringType . IsIn (
UtilConstants . DecType ,
UtilConstants . DateType ,
UtilConstants . DobType ,
UtilConstants . GuidType ,
UtilConstants . FloatType ,
UtilConstants . ShortType ,
UtilConstants . LongType ,
UtilConstants . IntType ,
UtilConstants . BoolType ) )
2019-02-06 17:53:40 +08:00
{
TempParseType = expression . Method . DeclaringType ;
2019-05-15 18:11:44 +08:00
return true ;
2019-02-06 17:53:40 +08:00
}
return false ;
}
2019-05-15 18:11:44 +08:00
public string GeDateFormat ( string formatString , string value )
{
2022-04-14 18:36:14 +08:00
if ( IsOracle ( ) & & formatString = = "yyyy-MM-dd HH:mm:ss" )
{
return $"to_char({value},'yyyy-MM-dd HH:mi:ss') " ;
}
else if ( IsOracle ( ) | | IsPg ( ) )
2021-12-02 20:11:23 +08:00
{
2021-12-02 20:20:59 +08:00
return $"to_char({value},'{formatString}') " ;
2021-12-02 20:11:23 +08:00
}
2021-12-15 21:21:43 +08:00
else if ( IsSqlite ( ) & & formatString = = "yyyy-MM-dd" )
{
return $"strftime('%Y-%m-%d', {value})" ;
}
2022-01-08 11:40:30 +08:00
else if ( IsSqlite ( ) & & formatString = = "yyyy-MM-dd HH:mm:ss" )
{
return $"strftime('%Y-%m-%d %H:%i:%S', {value})" ;
}
2022-01-08 11:41:47 +08:00
else if ( IsSqlite ( ) & & formatString = = "yyyy-MM-dd hh:mm:ss" )
{
return $"strftime('%Y-%m-%d %H:%i:%S', {value})" ;
}
2022-01-08 11:29:11 +08:00
else if ( IsSqlite ( ) & & formatString = = "yyyy-MM" )
{
return $"strftime('%Y-%m', {value})" ;
}
else if ( IsSqlite ( ) & & formatString = = "yyyyMM" )
{
return $"strftime('%Y%m', {value})" ;
}
else if ( IsSqlite ( ) & & formatString = = "yyyyMMdd" )
{
return $"strftime('%Y%m%d', {value})" ;
}
2021-12-15 21:43:03 +08:00
else if ( IsSqlite ( ) & & formatString . Contains ( "%" ) )
{
return $"strftime('{formatString}', {value})" ;
}
2021-12-15 21:21:43 +08:00
else if ( IsMySql ( ) & & formatString = = "yyyy-MM-dd" )
2021-12-02 20:20:59 +08:00
{
return $"DATE_FORMAT({value}, '%Y-%m-%d')" ;
}
2022-01-08 11:26:02 +08:00
else if ( IsMySql ( ) & & formatString = = "yyyy-MM" )
{
return $"DATE_FORMAT({value}, '%Y-%m')" ;
}
else if ( IsMySql ( ) & & formatString = = "yyyyMM" )
{
return $"DATE_FORMAT({value}, '%Y%m')" ;
}
else if ( IsMySql ( ) & & formatString = = "yyyyMMdd" )
{
return $"DATE_FORMAT({value}, '%Y%m%d')" ;
}
2022-01-08 11:40:30 +08:00
else if ( IsMySql ( ) & & formatString = = "yyyy-MM-dd HH:mm:ss" )
{
return $"DATE_FORMAT({value}, '%Y-%m-%d %H:%i:%S')" ;
}
2022-01-08 11:41:47 +08:00
else if ( IsMySql ( ) & & formatString = = "yyyy-MM-dd hh:mm:ss" )
{
return $"DATE_FORMAT({value}, '%Y-%m-%d %H:%i:%S')" ;
}
2021-12-15 21:43:03 +08:00
else if ( IsMySql ( ) & & formatString . Contains ( "%" ) )
{
return $"DATE_FORMAT({value}, '{formatString}')" ;
}
2021-12-02 20:20:59 +08:00
else if ( formatString = = "yyyy-MM-dd" & & IsSqlServer ( ) )
2021-12-02 20:00:19 +08:00
{
return $"CONVERT(varchar(100),convert(datetime,{value}), 23)" ;
}
2022-03-04 14:39:34 +08:00
else if ( formatString = = "yyyy-MM" & & IsSqlServer ( ) )
{
return $"CONVERT(varchar(7),convert(datetime,{value}), 23)" ;
}
2021-12-02 20:20:59 +08:00
else if ( formatString = = "yyyy-MM-dd HH:mm:ss" & & IsSqlServer ( ) )
2021-12-02 20:00:19 +08:00
{
return $"CONVERT(varchar(100),convert(datetime,{value}), 120)" ;
}
2021-12-02 20:20:59 +08:00
else if ( formatString = = "yyyy-MM-dd hh:mm:ss" & & IsSqlServer ( ) )
2021-12-02 20:00:19 +08:00
{
return $"CONVERT(varchar(100),convert(datetime,{value}), 120)" ;
}
2022-04-12 16:38:59 +08:00
else if ( formatString = = "yyyy-MM-dd HH:mm" & & IsSqlServer ( ) )
{
return $"CONVERT(varchar(16),convert(datetime,{value}), 120)" ;
}
else if ( formatString = = "yyyy-MM-dd hh:mm" & & IsSqlServer ( ) )
{
return $"CONVERT(varchar(16),convert(datetime,{value}), 120)" ;
}
2021-12-02 20:00:19 +08:00
else if ( formatString = = "yyyy-MM-dd hh:mm:ss.ms" & & IsSqlServer ( ) )
{
return $"CONVERT(varchar(100),convert(datetime,{value}), 121)" ;
}
2021-12-23 11:29:49 +08:00
else if ( IsSqlServer ( ) & & formatString ! = null & & formatString . IsInt ( ) )
2021-12-22 13:13:51 +08:00
{
return string . Format ( "CONVERT(varchar(100),convert(datetime,{0}), {1})" , value , formatString ) ;
}
2022-03-12 20:06:18 +08:00
else if ( IsSqlServer ( ) )
{
return string . Format ( "FORMAT({0},'{1}','en-US')" , value , formatString ) ;
}
2019-05-15 18:11:44 +08:00
var parameter = new MethodCallExpressionArgs ( ) { IsMember = true , MemberValue = DateType . Year } ;
var parameter2 = new MethodCallExpressionArgs ( ) { IsMember = true , MemberName = value } ;
var parameters = new MethodCallExpressionModel ( ) { Args = new List < MethodCallExpressionArgs > ( ) { parameter2 , parameter } } ;
var begin = @"^" ;
var end = @"$" ;
formatString = formatString . Replace ( "yyyy" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end ) ;
formatString = formatString . Replace ( "yy" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end ) ;
parameters . Args . Last ( ) . MemberValue = DateType . Month ;
2021-04-25 17:17:27 +08:00
if ( IsMySql ( ) )
{
formatString = formatString . Replace ( "MM" , begin + UtilMethods . ConvertStringToNumbers ( "LPAD(" + this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) + ",2,0)" ) + end ) ;
}
else if ( IsSqlite ( ) )
{
formatString = formatString . Replace ( "MM" , begin + UtilMethods . ConvertStringToNumbers ( "SUBSTR('00' ||" + this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) + ", -2, 2)" ) + end ) ;
}
else if ( IsPg ( ) )
{
formatString = formatString . Replace ( "MM" , begin + UtilMethods . ConvertStringToNumbers ( "lpad(cast(" + this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) + " as varchar(20)),2,'0')" ) + end ) ;
}
else if ( IsOracle ( ) )
{
formatString = formatString . Replace ( "MM" , begin + UtilMethods . ConvertStringToNumbers ( "lpad(cast(" + this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) + " as varchar(20)),2,'0')" ) + end ) ;
}
else
{
formatString = formatString . Replace ( "MM" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end ) ;
}
2019-05-15 18:11:44 +08:00
formatString = formatString . Replace ( "M" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end ) ;
parameters . Args . Last ( ) . MemberValue = DateType . Day ;
2021-09-29 22:57:07 +08:00
if ( IsSqlServer ( ) )
{
formatString = formatString . Replace ( "dd" , begin + UtilMethods . ConvertStringToNumbers ( string . Format ( "CASE WHEN LEN({0})=1 THEN '0'+ {0} else {0} end" , this . GetMethodValue ( "DateValue" , parameters ) ) ) + end ) ;
}
2019-05-15 18:11:44 +08:00
formatString = formatString . Replace ( "dd" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end ) ;
formatString = formatString . Replace ( "d" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end ) ;
parameters . Args . Last ( ) . MemberValue = DateType . Hour ;
formatString = Regex . Replace ( formatString , "hh" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end , RegexOptions . IgnoreCase ) ;
formatString = Regex . Replace ( formatString , "h" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end , RegexOptions . IgnoreCase ) ;
parameters . Args . Last ( ) . MemberValue = DateType . Minute ;
formatString = formatString . Replace ( "mm" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end ) ;
formatString = formatString . Replace ( "m" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end ) ;
parameters . Args . Last ( ) . MemberValue = DateType . Second ;
formatString = formatString . Replace ( "ss" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end ) ;
formatString = formatString . Replace ( "s" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end ) ;
2021-04-25 17:17:27 +08:00
if ( ! IsSqlite ( ) )
{
parameters . Args . Last ( ) . MemberValue = DateType . Millisecond ;
formatString = formatString . Replace ( "ms" , begin + UtilMethods . ConvertStringToNumbers ( this . GetMethodValue ( "DateValue" , parameters ) . ObjToString ( ) ) + end ) ;
}
2019-05-15 18:11:44 +08:00
var items = Regex . Matches ( formatString , @"\^\d+\$" ) . Cast < Match > ( ) . ToList ( ) ;
foreach ( var item in items )
{
formatString = formatString . Replace ( item . Value , "$@" + UtilMethods . ConvertNumbersToString ( item . Value . TrimStart ( '^' ) . TrimEnd ( '$' ) ) + "$" ) ;
}
var strings = formatString . TrimStart ( '$' ) . TrimEnd ( '$' ) . Split ( '$' ) ;
var joinStringParameter = new MethodCallExpressionModel ( )
{
Args = new List < MethodCallExpressionArgs > ( )
} ;
foreach ( var r in strings )
{
2022-01-08 11:12:48 +08:00
if ( r ! = "" & & r . Substring ( 0 , 1 ) = = "@" )
2019-05-15 18:11:44 +08:00
{
joinStringParameter . Args . Add ( new MethodCallExpressionArgs ( )
{
2020-10-27 15:21:26 +08:00
MemberName = r . TrimStart ( '@' )
2019-05-15 18:11:44 +08:00
} ) ;
}
else
{
var name = base . AppendParameter ( r ) ;
joinStringParameter . Args . Add ( new MethodCallExpressionArgs ( )
{
2020-10-27 15:21:26 +08:00
MemberName = name
2019-05-15 18:11:44 +08:00
} ) ;
}
}
return this . GetMethodValue ( "MergeString" , joinStringParameter ) . ObjToString ( ) ;
}
2021-09-29 22:57:07 +08:00
private bool IsSqlServer ( )
{
return this . Context is SqlServerExpressionContext ;
}
2021-04-25 17:17:27 +08:00
private bool IsMySql ( )
{
2022-02-01 16:32:11 +08:00
var name = this . Context . GetType ( ) . Name ;
var result = ( name = = "MySqlExpressionContext" ) ;
return result ;
2021-04-25 17:17:27 +08:00
}
private bool IsSqlite ( )
{
return this . Context is SqliteExpressionContext ;
}
private bool IsPg ( )
{
return this . Context is PostgreSQLExpressionContext ;
}
private bool IsOracle ( )
{
return this . Context is OracleExpressionContext ;
}
2017-01-07 21:54:51 +08:00
}
}