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