@@ -19,6 +19,8 @@ public class Parser<T> where T : class
1919 private int _take ;
2020 private int _skip ;
2121 private bool _sortDisabled = false ;
22+ private string _startsWithtoken = "*|" ;
23+ private string _endsWithToken = "|*" ;
2224
2325 private Dictionary < string , Expression > _converters = new Dictionary < string , Expression > ( ) ;
2426
@@ -166,6 +168,35 @@ public Parser<T> SetConverter(Expression<Func<T,object>> property, Expression<Fu
166168 return this ;
167169 }
168170
171+ ///<summary>
172+ /// SetStartsWithToken overrides the default StartsWith filter token
173+ /// The default token is *|
174+ /// By default all filters are in the form of string.Contains(FILTER_STRING)
175+ /// If a filter string is in the form of token + FILTER_STRING eg. *|app,
176+ /// the search will be translated to string.StartsWith("app")
177+ ///</summary>
178+ /// <param name="token">A string used to replace the default token</param>
179+ public Parser < T > SetStartsWithToken ( string token )
180+ {
181+ this . _startsWithtoken = token ;
182+ return this ;
183+ }
184+
185+ ///<summary>
186+ /// SetEndsWithToken overrides the default EndsWith filter token
187+ /// The default token is |*
188+ /// By default all filters are in the form of string.Contains(FILTER_STRING)
189+ /// If a filter string is in the form of FILTER_STRING + token eg. app|*,
190+ /// the search will be translated to string.EndsWith("app")
191+ ///</summary>
192+ /// <param name="token">A string used to replace the default token</param>
193+ public Parser < T > SetEndsWithToken ( string token )
194+ {
195+ this . _endsWithToken = token ;
196+ return this ;
197+ }
198+
199+
169200 private void ApplySort ( )
170201 {
171202 var sorted = false ;
@@ -268,6 +299,23 @@ private bool EnumerablFilter(T item)
268299
269300 }
270301
302+ private string GetFilterFn ( string filter )
303+ {
304+ switch ( filter )
305+ {
306+ case null :
307+ return Constants . CONTAINS_FN ;
308+ case var f when f . StartsWith ( _startsWithtoken ) && f . EndsWith ( _endsWithToken ) :
309+ return Constants . CONTAINS_FN ;
310+ case var f when f . StartsWith ( _startsWithtoken ) :
311+ return Constants . STARTS_WITH_FN ;
312+ case var f when f . EndsWith ( _endsWithToken ) :
313+ return Constants . ENDS_WITH_FN ;
314+ default :
315+ return Constants . CONTAINS_FN ;
316+ }
317+ }
318+
271319 /// <summary>
272320 /// Generate a lamda expression based on a search filter for all mapped columns
273321 /// </summary>
@@ -277,11 +325,12 @@ private Expression<Func<T, bool>> GenerateEntityFilter()
277325 var paramExpression = Expression . Parameter ( _type , "val" ) ;
278326
279327 string filter = _config [ Constants . SEARCH_KEY ] ;
280-
328+ string globalFilterFn = null ;
281329 ConstantExpression globalFilterConst = null ;
282330 Expression filterExpr = null ;
283331 if ( ! string . IsNullOrWhiteSpace ( filter ) )
284332 {
333+ globalFilterFn = GetFilterFn ( filter ) ;
285334 globalFilterConst = Expression . Constant ( filter . ToLower ( ) ) ;
286335 }
287336
@@ -293,6 +342,7 @@ private Expression<Func<T, bool>> GenerateEntityFilter()
293342 var prop = propMap . Value . Property ;
294343 var isString = prop . PropertyType == typeof ( string ) ;
295344 var hasCustomExpr = _converters . ContainsKey ( prop . Name ) ;
345+ string propFilterFn = null ;
296346
297347 if ( ( ! prop . CanWrite || ( ! _convertable . Any ( t => t == prop . PropertyType ) && ! isString ) ) && ! hasCustomExpr )
298348 {
@@ -302,6 +352,7 @@ private Expression<Func<T, bool>> GenerateEntityFilter()
302352 ConstantExpression individualFilterConst = null ;
303353 if ( ! string . IsNullOrWhiteSpace ( propMap . Value . Filter ) )
304354 {
355+ propFilterFn = GetFilterFn ( propMap . Value . Filter ) ;
305356 individualFilterConst = Expression . Constant ( propMap . Value . Filter . ToLower ( ) ) ;
306357 }
307358
@@ -323,7 +374,7 @@ private Expression<Func<T, bool>> GenerateEntityFilter()
323374
324375 if ( globalFilterConst != null )
325376 {
326- var globalTest = Expression . Call ( toLower , typeof ( string ) . GetMethod ( "Contains" , new [ ] { typeof ( string ) } ) , globalFilterConst ) ;
377+ var globalTest = Expression . Call ( toLower , typeof ( string ) . GetMethod ( globalFilterFn , new [ ] { typeof ( string ) } ) , globalFilterConst ) ;
327378
328379 if ( filterExpr == null )
329380 {
@@ -337,7 +388,7 @@ private Expression<Func<T, bool>> GenerateEntityFilter()
337388
338389 if ( individualFilterConst != null )
339390 {
340- individualConditions . Add ( Expression . Call ( toLower , typeof ( string ) . GetMethod ( "Contains" , new [ ] { typeof ( string ) } ) , individualFilterConst ) ) ;
391+ individualConditions . Add ( Expression . Call ( toLower , typeof ( string ) . GetMethod ( propFilterFn , new [ ] { typeof ( string ) } ) , individualFilterConst ) ) ;
341392
342393 }
343394
@@ -419,6 +470,10 @@ public class Constants
419470 public const string ORDER_DIRECTION_FORMAT = "order[{0}][dir]" ;
420471 public const string ORDERING_ENABLED = "ordering" ;
421472
473+ public const string CONTAINS_FN = "Contains" ;
474+ public const string STARTS_WITH_FN = "StartsWith" ;
475+ public const string ENDS_WITH_FN = "EndsWith" ;
476+
422477 public static string GetKey ( string format , string index )
423478 {
424479 return String . Format ( format , index ) ;
0 commit comments