1
- using System . Globalization ;
1
+ using JetBrains . Annotations ;
2
+ using System . Globalization ;
3
+ using System . Linq . Dynamic . Core . Validation ;
2
4
using System . Linq . Expressions ;
3
5
using System . Reflection ;
4
6
5
7
namespace System . Linq . Dynamic . Core . Parser
6
8
{
7
- internal static class ExpressionHelper
9
+ internal class ExpressionHelper : IExpressionHelper
8
10
{
9
- public static void ConvertNumericTypeToBiggestCommonTypeForBinaryOperator ( ref Expression left , ref Expression right )
11
+ private readonly IConstantExpressionWrapper _constantExpressionWrapper = new ConstantExpressionWrapper ( ) ;
12
+ private readonly ParsingConfig _parsingConfig ;
13
+
14
+ internal ExpressionHelper ( [ NotNull ] ParsingConfig parsingConfig )
15
+ {
16
+ Check . NotNull ( parsingConfig , nameof ( parsingConfig ) ) ;
17
+
18
+ _parsingConfig = parsingConfig ;
19
+ }
20
+
21
+ public void ConvertNumericTypeToBiggestCommonTypeForBinaryOperator ( ref Expression left , ref Expression right )
10
22
{
11
23
if ( left . Type == right . Type )
12
24
{
13
25
return ;
14
26
}
15
27
16
- if ( left . Type == typeof ( UInt64 ) || right . Type == typeof ( UInt64 ) )
28
+ if ( left . Type == typeof ( ulong ) || right . Type == typeof ( ulong ) )
17
29
{
18
- right = right . Type != typeof ( UInt64 ) ? Expression . Convert ( right , typeof ( UInt64 ) ) : right ;
19
- left = left . Type != typeof ( UInt64 ) ? Expression . Convert ( left , typeof ( UInt64 ) ) : left ;
30
+ right = right . Type != typeof ( ulong ) ? Expression . Convert ( right , typeof ( ulong ) ) : right ;
31
+ left = left . Type != typeof ( ulong ) ? Expression . Convert ( left , typeof ( ulong ) ) : left ;
20
32
}
21
- else if ( left . Type == typeof ( Int64 ) || right . Type == typeof ( Int64 ) )
33
+ else if ( left . Type == typeof ( long ) || right . Type == typeof ( long ) )
22
34
{
23
- right = right . Type != typeof ( Int64 ) ? Expression . Convert ( right , typeof ( Int64 ) ) : right ;
24
- left = left . Type != typeof ( Int64 ) ? Expression . Convert ( left , typeof ( Int64 ) ) : left ;
35
+ right = right . Type != typeof ( long ) ? Expression . Convert ( right , typeof ( long ) ) : right ;
36
+ left = left . Type != typeof ( long ) ? Expression . Convert ( left , typeof ( long ) ) : left ;
25
37
}
26
- else if ( left . Type == typeof ( UInt32 ) || right . Type == typeof ( UInt32 ) )
38
+ else if ( left . Type == typeof ( uint ) || right . Type == typeof ( uint ) )
27
39
{
28
- right = right . Type != typeof ( UInt32 ) ? Expression . Convert ( right , typeof ( UInt32 ) ) : right ;
29
- left = left . Type != typeof ( UInt32 ) ? Expression . Convert ( left , typeof ( UInt32 ) ) : left ;
40
+ right = right . Type != typeof ( uint ) ? Expression . Convert ( right , typeof ( uint ) ) : right ;
41
+ left = left . Type != typeof ( uint ) ? Expression . Convert ( left , typeof ( uint ) ) : left ;
30
42
}
31
- else if ( left . Type == typeof ( Int32 ) || right . Type == typeof ( Int32 ) )
43
+ else if ( left . Type == typeof ( int ) || right . Type == typeof ( int ) )
32
44
{
33
- right = right . Type != typeof ( Int32 ) ? Expression . Convert ( right , typeof ( Int32 ) ) : right ;
34
- left = left . Type != typeof ( Int32 ) ? Expression . Convert ( left , typeof ( Int32 ) ) : left ;
45
+ right = right . Type != typeof ( int ) ? Expression . Convert ( right , typeof ( int ) ) : right ;
46
+ left = left . Type != typeof ( int ) ? Expression . Convert ( left , typeof ( int ) ) : left ;
35
47
}
36
- else if ( left . Type == typeof ( UInt16 ) || right . Type == typeof ( UInt16 ) )
48
+ else if ( left . Type == typeof ( ushort ) || right . Type == typeof ( ushort ) )
37
49
{
38
- right = right . Type != typeof ( UInt16 ) ? Expression . Convert ( right , typeof ( UInt16 ) ) : right ;
39
- left = left . Type != typeof ( UInt16 ) ? Expression . Convert ( left , typeof ( UInt16 ) ) : left ;
50
+ right = right . Type != typeof ( ushort ) ? Expression . Convert ( right , typeof ( ushort ) ) : right ;
51
+ left = left . Type != typeof ( ushort ) ? Expression . Convert ( left , typeof ( ushort ) ) : left ;
40
52
}
41
- else if ( left . Type == typeof ( Int16 ) || right . Type == typeof ( Int16 ) )
53
+ else if ( left . Type == typeof ( short ) || right . Type == typeof ( short ) )
42
54
{
43
- right = right . Type != typeof ( Int16 ) ? Expression . Convert ( right , typeof ( Int16 ) ) : right ;
44
- left = left . Type != typeof ( Int16 ) ? Expression . Convert ( left , typeof ( Int16 ) ) : left ;
55
+ right = right . Type != typeof ( short ) ? Expression . Convert ( right , typeof ( short ) ) : right ;
56
+ left = left . Type != typeof ( short ) ? Expression . Convert ( left , typeof ( short ) ) : left ;
45
57
}
46
- else if ( left . Type == typeof ( Byte ) || right . Type == typeof ( Byte ) )
58
+ else if ( left . Type == typeof ( byte ) || right . Type == typeof ( byte ) )
47
59
{
48
- right = right . Type != typeof ( Byte ) ? Expression . Convert ( right , typeof ( Byte ) ) : right ;
49
- left = left . Type != typeof ( Byte ) ? Expression . Convert ( left , typeof ( Byte ) ) : left ;
60
+ right = right . Type != typeof ( byte ) ? Expression . Convert ( right , typeof ( byte ) ) : right ;
61
+ left = left . Type != typeof ( byte ) ? Expression . Convert ( left , typeof ( byte ) ) : left ;
50
62
}
51
63
}
52
64
53
- public static Expression GenerateAdd ( Expression left , Expression right )
65
+ public Expression GenerateAdd ( Expression left , Expression right )
54
66
{
55
67
return Expression . Add ( left , right ) ;
56
68
}
57
69
58
- public static Expression GenerateStringConcat ( Expression left , Expression right )
70
+ public Expression GenerateStringConcat ( Expression left , Expression right )
59
71
{
60
72
return GenerateStaticMethodCall ( "Concat" , left , right ) ;
61
73
}
62
74
63
- public static Expression GenerateSubtract ( Expression left , Expression right )
75
+ public Expression GenerateSubtract ( Expression left , Expression right )
64
76
{
65
77
return Expression . Subtract ( left , right ) ;
66
78
}
67
79
68
- public static Expression GenerateEqual ( Expression left , Expression right )
80
+ public Expression GenerateEqual ( Expression left , Expression right )
69
81
{
70
82
OptimizeForEqualityIfPossible ( ref left , ref right ) ;
83
+
84
+ WrapConstantExpressions ( ref left , ref right ) ;
85
+
71
86
return Expression . Equal ( left , right ) ;
72
87
}
73
88
74
- public static Expression GenerateNotEqual ( Expression left , Expression right )
89
+ public Expression GenerateNotEqual ( Expression left , Expression right )
75
90
{
76
91
OptimizeForEqualityIfPossible ( ref left , ref right ) ;
92
+
93
+ WrapConstantExpressions ( ref left , ref right ) ;
94
+
77
95
return Expression . NotEqual ( left , right ) ;
78
96
}
79
97
80
- public static Expression GenerateGreaterThan ( Expression left , Expression right )
98
+ public Expression GenerateGreaterThan ( Expression left , Expression right )
81
99
{
82
100
if ( left . Type == typeof ( string ) )
83
101
{
@@ -91,10 +109,12 @@ public static Expression GenerateGreaterThan(Expression left, Expression right)
91
109
return Expression . GreaterThan ( leftPart , rightPart ) ;
92
110
}
93
111
112
+ WrapConstantExpressions ( ref left , ref right ) ;
113
+
94
114
return Expression . GreaterThan ( left , right ) ;
95
115
}
96
116
97
- public static Expression GenerateGreaterThanEqual ( Expression left , Expression right )
117
+ public Expression GenerateGreaterThanEqual ( Expression left , Expression right )
98
118
{
99
119
if ( left . Type == typeof ( string ) )
100
120
{
@@ -107,10 +127,12 @@ public static Expression GenerateGreaterThanEqual(Expression left, Expression ri
107
127
right . Type . GetTypeInfo ( ) . IsEnum ? Expression . Convert ( right , Enum . GetUnderlyingType ( right . Type ) ) : right ) ;
108
128
}
109
129
130
+ WrapConstantExpressions ( ref left , ref right ) ;
131
+
110
132
return Expression . GreaterThanOrEqual ( left , right ) ;
111
133
}
112
134
113
- public static Expression GenerateLessThan ( Expression left , Expression right )
135
+ public Expression GenerateLessThan ( Expression left , Expression right )
114
136
{
115
137
if ( left . Type == typeof ( string ) )
116
138
{
@@ -123,10 +145,12 @@ public static Expression GenerateLessThan(Expression left, Expression right)
123
145
right . Type . GetTypeInfo ( ) . IsEnum ? Expression . Convert ( right , Enum . GetUnderlyingType ( right . Type ) ) : right ) ;
124
146
}
125
147
148
+ WrapConstantExpressions ( ref left , ref right ) ;
149
+
126
150
return Expression . LessThan ( left , right ) ;
127
151
}
128
152
129
- public static Expression GenerateLessThanEqual ( Expression left , Expression right )
153
+ public Expression GenerateLessThanEqual ( Expression left , Expression right )
130
154
{
131
155
if ( left . Type == typeof ( string ) )
132
156
{
@@ -139,15 +163,15 @@ public static Expression GenerateLessThanEqual(Expression left, Expression right
139
163
right . Type . GetTypeInfo ( ) . IsEnum ? Expression . Convert ( right , Enum . GetUnderlyingType ( right . Type ) ) : right ) ;
140
164
}
141
165
166
+ WrapConstantExpressions ( ref left , ref right ) ;
167
+
142
168
return Expression . LessThanOrEqual ( left , right ) ;
143
169
}
144
170
145
- public static void OptimizeForEqualityIfPossible ( ref Expression left , ref Expression right )
171
+ public void OptimizeForEqualityIfPossible ( ref Expression left , ref Expression right )
146
172
{
147
173
// The goal here is to provide the way to convert some types from the string form in a way that is compatible with Linq to Entities.
148
- //
149
174
// The Expression.Call(typeof(Guid).GetMethod("Parse"), right); does the job only for Linq to Object but Linq to Entities.
150
- //
151
175
Type leftType = left . Type ;
152
176
Type rightType = right . Type ;
153
177
@@ -162,7 +186,7 @@ public static void OptimizeForEqualityIfPossible(ref Expression left, ref Expres
162
186
}
163
187
}
164
188
165
- public static Expression OptimizeStringForEqualityIfPossible ( string text , Type type )
189
+ public Expression OptimizeStringForEqualityIfPossible ( string text , Type type )
166
190
{
167
191
if ( type == typeof ( DateTime ) && DateTime . TryParse ( text , CultureInfo . InvariantCulture , DateTimeStyles . None , out DateTime dateTime ) )
168
192
{
@@ -186,20 +210,29 @@ public static Expression OptimizeStringForEqualityIfPossible(string text, Type t
186
210
return null ;
187
211
}
188
212
189
- static MethodInfo GetStaticMethod ( string methodName , Expression left , Expression right )
213
+ private MethodInfo GetStaticMethod ( string methodName , Expression left , Expression right )
190
214
{
191
- var methodInfo = left . Type . GetMethod ( methodName , new [ ] { left . Type , right . Type } ) ;
215
+ var methodInfo = left . Type . GetMethod ( methodName , new [ ] { left . Type , right . Type } ) ;
192
216
if ( methodInfo == null )
193
217
{
194
- methodInfo = right . Type . GetMethod ( methodName , new [ ] { left . Type , right . Type } ) ;
218
+ methodInfo = right . Type . GetMethod ( methodName , new [ ] { left . Type , right . Type } ) ;
195
219
}
196
220
197
221
return methodInfo ;
198
222
}
199
223
200
- static Expression GenerateStaticMethodCall ( string methodName , Expression left , Expression right )
224
+ private Expression GenerateStaticMethodCall ( string methodName , Expression left , Expression right )
201
225
{
202
226
return Expression . Call ( null , GetStaticMethod ( methodName , left , right ) , new [ ] { left , right } ) ;
203
227
}
228
+
229
+ private void WrapConstantExpressions ( ref Expression left , ref Expression right )
230
+ {
231
+ if ( _parsingConfig . UseParameterizedNamesInDynamicQuery )
232
+ {
233
+ _constantExpressionWrapper . Wrap ( ref left ) ;
234
+ _constantExpressionWrapper . Wrap ( ref right ) ;
235
+ }
236
+ }
204
237
}
205
238
}
0 commit comments