@@ -906,6 +906,30 @@ public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc)
906906 if ( exp3 . Arguments . Count > 0 && exp3 . Object != null ) return ExpressionBinary ( "=" , exp3 . Object , exp3 . Arguments [ 0 ] , tsc ) ;
907907 if ( exp3 . Arguments . Count > 1 && exp3 . Method . DeclaringType == typeof ( object ) ) return ExpressionBinary ( "=" , exp3 . Arguments [ 0 ] , exp3 . Arguments [ 1 ] , tsc ) ;
908908 }
909+ if ( exp3 . Method . Name == "Any" && exp3 . Method . DeclaringType == typeof ( Enumerable ) )
910+ {
911+ //Where(a => idArray.Any(p => (a.Id == p.Key || a.RoleName == p.Key) && a.RoleType == p.Type))
912+ var exp3MethodGenArgs = exp3 . Method . GetGenericArguments ( ) ;
913+ var exp3MethodArgs = exp3 . Method . GetParameters ( ) ;
914+ if ( exp3MethodGenArgs . Length == 1 && exp3MethodArgs . Length == 2 && exp3MethodArgs [ 1 ] . ParameterType == typeof ( Func < , > ) . MakeGenericType ( exp3MethodGenArgs [ 0 ] , typeof ( bool ) ) )
915+ {
916+ var exp3Value = ExpressionGetValue ( exp3 . Arguments [ 0 ] , out var exp3ValueSuccess ) ;
917+ if ( exp3ValueSuccess )
918+ {
919+ if ( exp3Value == null ) return "1=2" ;
920+ var exp3ValueIE = exp3Value as IEnumerable ;
921+ var exp3NewExpVisitor = new ReplaceParameterVisitor ( ) ;
922+ var exp3sb = new StringBuilder ( ) ;
923+ foreach ( var exp3ValueItem in exp3ValueIE )
924+ {
925+ var exp3NewExp = exp3NewExpVisitor . Modify ( exp3 . Arguments [ 1 ] as LambdaExpression , Expression . Constant ( exp3ValueItem , exp3MethodGenArgs [ 0 ] ) ) ;
926+ exp3sb . Append ( " OR " ) . Append ( ExpressionLambdaToSql ( exp3NewExp , tsc ) ) ;
927+ }
928+ if ( exp3sb . Length == 0 ) return "1=2" ;
929+ return exp3sb . Remove ( 0 , 4 ) . ToString ( ) ;
930+ }
931+ }
932+ }
909933 if ( callType . FullName . StartsWith ( "FreeSql.ISelectGroupingAggregate`" ) )
910934 {
911935 switch ( exp3 . Method . Name )
@@ -1736,6 +1760,86 @@ public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc)
17361760 public abstract string ExpressionLambdaToSqlOther ( Expression exp , ExpTSC tsc ) ;
17371761 public string ExpressionConstDateTime ( Expression exp ) => exp is ConstantExpression operandExpConst ? formatSql ( Utils . GetDataReaderValue ( typeof ( DateTime ) , operandExpConst . Value ) , null , null , null ) : null ;
17381762
1763+ public static object ExpressionGetValue ( Expression exp , out bool success )
1764+ {
1765+ success = true ;
1766+ var expStack = new Stack < Expression > ( ) ;
1767+ var expStackConstOrMemberCount = 1 ;
1768+ var exp2 = exp ;
1769+ while ( true )
1770+ {
1771+ switch ( exp2 ? . NodeType )
1772+ {
1773+ case ExpressionType . Constant :
1774+ expStack . Push ( exp2 ) ;
1775+ expStackConstOrMemberCount ++ ;
1776+ break ;
1777+ case ExpressionType . Parameter :
1778+ expStack . Push ( exp2 ) ;
1779+ break ;
1780+ case ExpressionType . MemberAccess :
1781+ expStack . Push ( exp2 ) ;
1782+ exp2 = ( exp2 as MemberExpression ) . Expression ;
1783+ expStackConstOrMemberCount ++ ;
1784+ if ( exp2 == null ) break ;
1785+ continue ;
1786+ case ExpressionType . Call :
1787+ var callExp = exp2 as MethodCallExpression ;
1788+ expStack . Push ( exp2 ) ;
1789+ exp2 = callExp . Object ;
1790+ if ( exp2 == null ) break ;
1791+ continue ;
1792+ case ExpressionType . TypeAs :
1793+ case ExpressionType . Convert :
1794+ var oper2 = ( exp2 as UnaryExpression ) . Operand ;
1795+ if ( oper2 . NodeType == ExpressionType . Parameter )
1796+ {
1797+ var oper2Parm = oper2 as ParameterExpression ;
1798+ expStack . Push ( exp2 . Type . IsAbstract || exp2 . Type . IsInterface ? oper2Parm : Expression . Parameter ( exp2 . Type , oper2Parm . Name ) ) ;
1799+ }
1800+ else
1801+ expStack . Push ( oper2 ) ;
1802+ break ;
1803+ }
1804+ break ;
1805+ }
1806+ if ( expStack . Any ( ) && expStack . First ( ) . NodeType != ExpressionType . Parameter )
1807+ {
1808+ if ( expStackConstOrMemberCount == expStack . Count )
1809+ {
1810+ object firstValue = null ;
1811+ switch ( expStack . First ( ) . NodeType )
1812+ {
1813+ case ExpressionType . Constant :
1814+ var expStackFirst = expStack . Pop ( ) as ConstantExpression ;
1815+ firstValue = expStackFirst ? . Value ;
1816+ break ;
1817+ case ExpressionType . MemberAccess :
1818+ var expStackFirstMem = expStack . First ( ) as MemberExpression ;
1819+ if ( expStackFirstMem . Expression ? . NodeType == ExpressionType . Constant )
1820+ firstValue = ( expStackFirstMem . Expression as ConstantExpression ) ? . Value ;
1821+ else
1822+ return Expression . Lambda ( exp ) . Compile ( ) . DynamicInvoke ( ) ;
1823+ break ;
1824+ }
1825+ while ( expStack . Any ( ) )
1826+ {
1827+ var expStackItem = expStack . Pop ( ) as MemberExpression ;
1828+ if ( expStackItem . Member . MemberType == MemberTypes . Property )
1829+ firstValue = ( ( PropertyInfo ) expStackItem . Member ) . GetValue ( firstValue , null ) ;
1830+ else if ( expStackItem . Member . MemberType == MemberTypes . Field )
1831+ firstValue = ( ( FieldInfo ) expStackItem . Member ) . GetValue ( firstValue ) ;
1832+ }
1833+ return firstValue ;
1834+ }
1835+ return Expression . Lambda ( exp ) . Compile ( ) . DynamicInvoke ( ) ;
1836+ }
1837+ if ( exp . IsParameter ( ) == false )
1838+ return Expression . Lambda ( exp ) . Compile ( ) . DynamicInvoke ( ) ;
1839+ success = false ;
1840+ return null ;
1841+ }
1842+
17391843 public enum ExpressionStyle
17401844 {
17411845 Where , AsSelect , SelectColumns
@@ -1889,18 +1993,18 @@ public string GetWhereCascadeSql(SelectTableInfo tb, List<GlobalFilter.Item> fil
18891993 }
18901994 public class ReplaceParameterVisitor : ExpressionVisitor
18911995 {
1892- private ParameterExpression parameter ;
1996+ private Expression _replaceExp ;
18931997 private ParameterExpression oldParameter ;
1894- public Expression Modify ( LambdaExpression lambda , ParameterExpression parameter )
1998+ public Expression Modify ( LambdaExpression lambda , Expression replaceExp )
18951999 {
1896- this . parameter = parameter ;
2000+ this . _replaceExp = replaceExp ;
18972001 this . oldParameter = lambda . Parameters . FirstOrDefault ( ) ;
18982002 return Visit ( lambda . Body ) ;
18992003 }
19002004 protected override Expression VisitMember ( MemberExpression node )
19012005 {
19022006 if ( node . Expression ? . NodeType == ExpressionType . Parameter && node . Expression == oldParameter )
1903- return Expression . Property ( parameter , node . Member . Name ) ;
2007+ return Expression . Property ( _replaceExp , node . Member . Name ) ;
19042008 return base . VisitMember ( node ) ;
19052009 }
19062010 }
0 commit comments