@@ -10,7 +10,7 @@ namespace DataTablesParser
10
10
{
11
11
public class Parser < T > where T : class
12
12
{
13
- private IQueryable < T > _queryable ;
13
+ private IQueryable < T > _query ;
14
14
private readonly Dictionary < string , string > _config ;
15
15
private readonly Type _type ;
16
16
private IDictionary < int , PropertyMap > _propertyMap ;
@@ -21,6 +21,7 @@ public class Parser<T> where T : class
21
21
private bool _sortDisabled = false ;
22
22
private string _startsWithtoken = "*|" ;
23
23
private string _endsWithToken = "|*" ;
24
+ private bool _isEnumerableQuery ;
24
25
25
26
private Dictionary < string , Expression > _converters = new Dictionary < string , Expression > ( ) ;
26
27
@@ -35,12 +36,13 @@ public class Parser<T> where T : class
35
36
typeof ( double ) ,
36
37
typeof ( Nullable < double > ) ,
37
38
typeof ( DateTime ) ,
38
- typeof ( Nullable < DateTime > )
39
+ typeof ( Nullable < DateTime > ) ,
40
+ typeof ( string )
39
41
} ;
40
42
41
- public Parser ( IEnumerable < KeyValuePair < string , StringValues > > configParams , IQueryable < T > queryable )
43
+ public Parser ( IEnumerable < KeyValuePair < string , StringValues > > configParams , IQueryable < T > query )
42
44
{
43
- _queryable = queryable ;
45
+ _query = query ;
44
46
_config = configParams . ToDictionary ( k => k . Key , v=> v . Value . First ( ) . Trim ( ) ) ;
45
47
_type = typeof ( T ) ;
46
48
@@ -91,6 +93,7 @@ where Regex.IsMatch(param.Key,Constants.COLUMN_PROPERTY_PATTERN)
91
93
}
92
94
93
95
_sortDisabled = _config . ContainsKey ( Constants . ORDERING_ENABLED ) && _config [ Constants . ORDERING_ENABLED ] == "false" ;
96
+ _isEnumerableQuery = _query is System . Linq . EnumerableQuery ;
94
97
}
95
98
96
99
public Results < T > Parse ( )
@@ -101,7 +104,7 @@ public Results<T> Parse()
101
104
list . draw = int . Parse ( _config [ Constants . DRAW ] ) ;
102
105
103
106
// count the record BEFORE filtering
104
- list . recordsTotal = _queryable . Count ( ) ;
107
+ list . recordsTotal = _query . Count ( ) ;
105
108
106
109
//sort results if sorting isn't disabled or skip needs to be called
107
110
if ( ! _sortDisabled || _skip > 0 )
@@ -115,26 +118,18 @@ public Results<T> Parse()
115
118
//Use query expression to return filtered paged list
116
119
//This is a best effort to avoid client evaluation whenever possible
117
120
//No good api to determine support for .ToString() on a type
118
- if ( _queryable . Provider is System . Linq . EnumerableQuery && hasFilterText )
119
- {
120
- resultQuery = _queryable . Where ( EnumerablFilter )
121
- . Skip ( _skip )
122
- . Take ( _take ) ;
123
-
124
- list . recordsFiltered = _queryable . Count ( EnumerablFilter ) ;
125
- }
126
- else if ( hasFilterText )
121
+ if ( hasFilterText )
127
122
{
128
123
var entityFilter = GenerateEntityFilter ( ) ;
129
- resultQuery = _queryable . Where ( entityFilter )
124
+ resultQuery = _query . Where ( entityFilter )
130
125
. Skip ( _skip )
131
126
. Take ( _take ) ;
132
127
133
- list . recordsFiltered = _queryable . Count ( entityFilter ) ;
128
+ list . recordsFiltered = _query . Count ( entityFilter ) ;
134
129
}
135
130
else
136
131
{
137
- resultQuery = _queryable
132
+ resultQuery = _query
138
133
. Skip ( _skip )
139
134
. Take ( _take ) ;
140
135
@@ -238,13 +233,13 @@ private void ApplySort()
238
233
methodName = sorted ? "ThenByDescending" : "OrderByDescending" ;
239
234
}
240
235
241
- _queryable = typeof ( Queryable ) . GetMethods ( ) . Single (
236
+ _query = typeof ( Queryable ) . GetMethods ( ) . Single (
242
237
method => method . Name == methodName
243
238
&& method . IsGenericMethodDefinition
244
239
&& method . GetGenericArguments ( ) . Length == 2
245
240
&& method . GetParameters ( ) . Length == 2 )
246
241
. MakeGenericMethod ( _type , propType )
247
- . Invoke ( null , new object [ ] { _queryable , propertyExpr } ) as IOrderedQueryable < T > ;
242
+ . Invoke ( null , new object [ ] { _query , propertyExpr } ) as IOrderedQueryable < T > ;
248
243
249
244
sorted = true ;
250
245
}
@@ -258,47 +253,18 @@ private void ApplySort()
258
253
var delegateType = Expression . GetFuncType ( _type , propType ) ;
259
254
var propertyExpr = Expression . Lambda ( delegateType , firstProp , paramExpr ) ;
260
255
261
- _queryable = typeof ( Queryable ) . GetMethods ( ) . Single (
256
+ _query = typeof ( Queryable ) . GetMethods ( ) . Single (
262
257
method => method . Name == "OrderBy"
263
258
&& method . IsGenericMethodDefinition
264
259
&& method . GetGenericArguments ( ) . Length == 2
265
260
&& method . GetParameters ( ) . Length == 2 )
266
261
. MakeGenericMethod ( _type , propType )
267
- . Invoke ( null , new object [ ] { _queryable , propertyExpr } ) as IOrderedQueryable < T > ;
262
+ . Invoke ( null , new object [ ] { _query , propertyExpr } ) as IOrderedQueryable < T > ;
268
263
269
264
}
270
265
271
266
}
272
267
273
-
274
- private bool EnumerablFilter ( T item )
275
- {
276
-
277
- var globalFilter = _config [ Constants . SEARCH_KEY ] ;
278
- var globalMatch = false ;
279
- var individualMatch = true ;
280
- foreach ( var map in _propertyMap . Where ( m => m . Value . Searchable ) )
281
- {
282
- var propValue = Convert . ToString ( map . Value . Property . GetValue ( item , null ) ) . ToLower ( ) ;
283
- if ( ! string . IsNullOrWhiteSpace ( globalFilter ) && propValue . Contains ( globalFilter . ToLower ( ) ) )
284
- {
285
- globalMatch = true ;
286
- }
287
- if ( ! string . IsNullOrWhiteSpace ( map . Value . Filter ) && ! propValue . Contains ( map . Value . Filter . ToLower ( ) ) )
288
- {
289
- individualMatch = false ;
290
- }
291
- }
292
-
293
- if ( ! string . IsNullOrWhiteSpace ( globalFilter ) )
294
- {
295
- return globalMatch && individualMatch ;
296
- }
297
-
298
- return individualMatch ;
299
-
300
- }
301
-
302
268
private string GetFilterFn ( string filter )
303
269
{
304
270
switch ( filter )
@@ -344,7 +310,7 @@ private Expression<Func<T, bool>> GenerateEntityFilter()
344
310
var hasCustomExpr = _converters . ContainsKey ( prop . Name ) ;
345
311
string propFilterFn = null ;
346
312
347
- if ( ( ! prop . CanWrite || ( ! _convertable . Any ( t => t == prop . PropertyType ) && ! isString ) ) && ! hasCustomExpr )
313
+ if ( ! prop . CanWrite || ( ! _convertable . Any ( t => t == prop . PropertyType ) && ! hasCustomExpr && ! _isEnumerableQuery ) )
348
314
{
349
315
continue ;
350
316
}
0 commit comments