@@ -20,6 +20,7 @@ public class Parser<T> where T : class
2020 private int _skip ;
2121 private bool _sortDisabled = false ;
2222
23+ private Dictionary < string , Expression > _converters = new Dictionary < string , Expression > ( ) ;
2324
2425 private Type [ ] _convertable =
2526 {
@@ -63,7 +64,12 @@ where Regex.IsMatch(param.Key,Constants.COLUMN_PROPERTY_PATTERN)
6364 }
6465 } ) . Distinct ( ) . ToDictionary ( k => k . index , v => v . map ) ;
6566
66-
67+
68+ if ( _propertyMap . Count == 0 )
69+ {
70+ throw new Exception ( "No properties were found in request. Please map datatable field names to properties in T" ) ;
71+ }
72+
6773 if ( _config . ContainsKey ( Constants . DISPLAY_START ) )
6874 {
6975 int . TryParse ( _config [ Constants . DISPLAY_START ] , out _skip ) ;
@@ -137,6 +143,28 @@ public Results<T> Parse()
137143 return list ;
138144 }
139145
146+ ///<summary>
147+ /// SetConverter accepts a custom expression for converting a property in T to string.
148+ /// This will be used during filtering.
149+ ///</summary>
150+ /// <param name="property">A lambda expression with a member expression as the body</param>
151+ /// <param name="tostring">A lambda given T returns a string by performing a sql translatable operation on property</param>
152+ public Parser < T > SetConverter ( Expression < Func < T , object > > property , Expression < Func < T , string > > tostring )
153+ {
154+ Console . WriteLine ( property . Body . NodeType ) ;
155+
156+ var memberExp = ( ( UnaryExpression ) property . Body ) . Operand as MemberExpression ;
157+
158+ if ( memberExp == null )
159+ {
160+ throw new ArgumentException ( "Body in property must be a member expression" ) ;
161+ }
162+
163+ _converters [ memberExp . Member . Name ] = tostring . Body ;
164+
165+ return this ;
166+ }
167+
140168 private void ApplySort ( )
141169 {
142170 var sorted = false ;
@@ -240,19 +268,26 @@ private Expression<Func<T, bool>> GenerateEntityFilter()
240268 var searchExpression = Expression . Constant ( search . ToLower ( ) ) ;
241269 var paramExpression = Expression . Parameter ( _type , "val" ) ;
242270 List < MethodCallExpression > searchProps = new List < MethodCallExpression > ( ) ;
271+ var modifier = new ModifyParam ( paramExpression ) ;
243272
244273 foreach ( var propMap in _propertyMap )
245274 {
246275 var prop = propMap . Value . Property ;
247276 var isString = prop . PropertyType == typeof ( string ) ;
248- if ( ! prop . CanWrite || ! propMap . Value . Searchable || ( ! _convertable . Any ( t => t == prop . PropertyType ) && ! isString ) )
277+ var hasCustom = _converters . ContainsKey ( prop . Name ) ;
278+
279+ if ( ( ! prop . CanWrite || ! propMap . Value . Searchable || ( ! _convertable . Any ( t => t == prop . PropertyType ) && ! isString ) ) && ! hasCustom )
249280 {
250281 continue ;
251282 }
252283
253284 Expression propExp = Expression . Property ( paramExpression , prop ) ;
254285
255- if ( ! isString )
286+ if ( hasCustom )
287+ {
288+ propExp = modifier . Visit ( _converters [ prop . Name ] ) ;
289+ }
290+ else if ( ! isString )
256291 {
257292 var toString = prop . PropertyType . GetMethod ( "ToString" , Type . EmptyTypes ) ;
258293
@@ -267,8 +302,9 @@ private Expression<Func<T, bool>> GenerateEntityFilter()
267302 }
268303
269304 var propertyQuery = searchProps . ToArray ( ) ;
270- // we now need to compound the expression by starting with the first
271- // expression and build through the iterator
305+
306+ //This will all be converted to a giant WHERE clause if translated to sql
307+ //Add the first expression
272308 Expression compoundExpression = propertyQuery [ 0 ] ;
273309
274310 // add the other expressions
@@ -284,6 +320,22 @@ private Expression<Func<T, bool>> GenerateEntityFilter()
284320
285321
286322
323+ public class ModifyParam : ExpressionVisitor
324+ {
325+ private ParameterExpression _replace ;
326+
327+ public ModifyParam ( ParameterExpression p )
328+ {
329+ _replace = p ;
330+ }
331+
332+ protected override Expression VisitParameter ( ParameterExpression node )
333+ {
334+ return _replace ;
335+ }
336+
337+ }
338+
287339 private class PropertyMap
288340 {
289341 public PropertyInfo Property { get ; set ; }
0 commit comments