1
+ using System ;
2
+ using System . Collections . Generic ;
3
+ using System . Linq ;
4
+ using System . Linq . Expressions ;
5
+ using System . Reflection ;
6
+ using System . Web ;
7
+ using System . Web . Mvc ;
8
+
9
+ namespace mesoft . gridview . Models
10
+ {
11
+ public static class ExpresssionBuilder
12
+ {
13
+ private static readonly MethodInfo containsMethod = typeof ( string ) . GetMethod ( "Contains" ) ;
14
+ private static readonly MethodInfo startsWithMethod = typeof ( string ) . GetMethod ( "StartsWith" , new Type [ ] { typeof ( string ) } ) ;
15
+ private static readonly MethodInfo endsWithMethod = typeof ( string ) . GetMethod ( "EndsWith" , new Type [ ] { typeof ( string ) } ) ;
16
+
17
+
18
+ public static Expression < Func < T , bool > > GetExpression < T > ( IList < FilterObject > filters )
19
+ {
20
+ if ( filters . Count == 0 )
21
+ return null ;
22
+
23
+ ParameterExpression param = Expression . Parameter ( typeof ( T ) , "t" ) ;
24
+ Expression exp = null ;
25
+
26
+ if ( filters . Count == 1 )
27
+ exp = GetExpression < T > ( param , filters [ 0 ] ) ;
28
+ else if ( filters . Count == 2 )
29
+ exp = GetExpression < T > ( param , filters [ 0 ] , filters [ 1 ] ) ;
30
+ else
31
+ {
32
+ while ( filters . Count > 0 )
33
+ {
34
+ var f1 = filters [ 0 ] ;
35
+ var f2 = filters [ 1 ] ;
36
+
37
+ if ( exp == null )
38
+ exp = GetExpression < T > ( param , filters [ 0 ] , filters [ 1 ] ) ;
39
+ else
40
+ exp = Expression . AndAlso ( exp , GetExpression < T > ( param , filters [ 0 ] , filters [ 1 ] ) ) ;
41
+
42
+ filters . Remove ( f1 ) ;
43
+ filters . Remove ( f2 ) ;
44
+
45
+ if ( filters . Count == 1 )
46
+ {
47
+ exp = Expression . AndAlso ( exp , GetExpression < T > ( param , filters [ 0 ] ) ) ;
48
+ filters . RemoveAt ( 0 ) ;
49
+ }
50
+ }
51
+ }
52
+
53
+ return Expression . Lambda < Func < T , bool > > ( exp , param ) ;
54
+ }
55
+
56
+ private static Expression GetExpression < T > ( ParameterExpression param , FilterObject filter )
57
+ {
58
+ MemberExpression member = Expression . Property ( param , filter . Column ) ;
59
+ //ConstantExpression constant = Expression.Constant(filter.Value);
60
+
61
+ // NEW LOGIC to handle nullable Decimal and DateTime values
62
+ UnaryExpression constant = null ;
63
+ if ( member . Type == typeof ( Decimal ? ) )
64
+ {
65
+ constant = Expression . Convert ( Expression . Constant ( Decimal . Parse ( filter . Value ) ) , member . Type ) ;
66
+ }
67
+ else if ( member . Type == typeof ( DateTime ? ) )
68
+ {
69
+ constant = Expression . Convert ( Expression . Constant ( DateTime . Parse ( filter . Value ) ) , member . Type ) ;
70
+ }
71
+ else
72
+ {
73
+ constant = Expression . Convert ( Expression . Constant ( filter . Value ) , member . Type ) ;
74
+ }
75
+
76
+
77
+ switch ( filter . Operator )
78
+ {
79
+ case FilterOperator . Equals :
80
+ return Expression . Equal ( member , constant ) ;
81
+
82
+ case FilterOperator . GreaterThan :
83
+ return Expression . GreaterThan ( member , constant ) ;
84
+
85
+ case FilterOperator . GreaterThanOrEqual :
86
+ return Expression . GreaterThanOrEqual ( member , constant ) ;
87
+
88
+ case FilterOperator . LessThan :
89
+ return Expression . LessThan ( member , constant ) ;
90
+
91
+ case FilterOperator . LessThanOrEqual :
92
+ return Expression . LessThanOrEqual ( member , constant ) ;
93
+
94
+ case FilterOperator . Contains :
95
+ return Expression . Call ( member , containsMethod , constant ) ;
96
+
97
+ case FilterOperator . StartsWith :
98
+ return Expression . Call ( member , startsWithMethod , constant ) ;
99
+
100
+ case FilterOperator . EndsWith :
101
+ return Expression . Call ( member , endsWithMethod , constant ) ;
102
+
103
+ case FilterOperator . NotEqual :
104
+ return Expression . Negate ( Expression . Equal ( member , constant ) ) ;
105
+ }
106
+
107
+ return null ;
108
+ }
109
+
110
+ private static BinaryExpression GetExpression < T > ( ParameterExpression param , FilterObject filter1 , FilterObject filter2 )
111
+ {
112
+ Expression bin1 = GetExpression < T > ( param , filter1 ) ;
113
+ Expression bin2 = GetExpression < T > ( param , filter2 ) ;
114
+
115
+ return Expression . AndAlso ( bin1 , bin2 ) ;
116
+ }
117
+ }
118
+ }
0 commit comments