@@ -10,10 +10,10 @@ namespace DataTablesParser
10
10
{
11
11
public class Parser < T > where T : class
12
12
{
13
- private IQueryable < T > _queriable ;
13
+ private IQueryable < T > _queryable ;
14
14
private readonly Dictionary < string , string > _config ;
15
15
private readonly Type _type ;
16
- private IDictionary < int , PropertyMapping > _propertyMap ;
16
+ private IDictionary < int , PropertyMap > _propertyMap ;
17
17
18
18
//Global configs
19
19
private int _take ;
@@ -35,9 +35,9 @@ public class Parser<T> where T : class
35
35
typeof ( Nullable < DateTime > )
36
36
} ;
37
37
38
- public Parser ( IEnumerable < KeyValuePair < string , StringValues > > configParams , IQueryable < T > queriable )
38
+ public Parser ( IEnumerable < KeyValuePair < string , StringValues > > configParams , IQueryable < T > queryable )
39
39
{
40
- _queriable = queriable ;
40
+ _queryable = queryable ;
41
41
_config = configParams . ToDictionary ( k => k . Key , v=> v . Value . First ( ) . Trim ( ) ) ;
42
42
_type = typeof ( T ) ;
43
43
@@ -55,7 +55,7 @@ where Regex.IsMatch(param.Key,Constants.COLUMN_PROPERTY_PATTERN)
55
55
select new
56
56
{
57
57
index = int . Parse ( index ) ,
58
- map = new PropertyMapping
58
+ map = new PropertyMap
59
59
{
60
60
Property = prop ,
61
61
Searchable = searchable ,
@@ -82,15 +82,15 @@ where Regex.IsMatch(param.Key,Constants.COLUMN_PROPERTY_PATTERN)
82
82
_sortDisabled = _config . ContainsKey ( Constants . ORDERING_ENABLED ) && _config [ Constants . ORDERING_ENABLED ] == "false" ;
83
83
}
84
84
85
- public FormatedList < T > Parse ( )
85
+ public Results < T > Parse ( )
86
86
{
87
- var list = new FormatedList < T > ( ) ;
87
+ var list = new Results < T > ( ) ;
88
88
89
- // parse the echo property (must be returned as int to prevent XSS-attack)
89
+ // parse the echo property
90
90
list . draw = int . Parse ( _config [ Constants . DRAW ] ) ;
91
91
92
92
// count the record BEFORE filtering
93
- list . recordsTotal = _queriable . Count ( ) ;
93
+ list . recordsTotal = _queryable . Count ( ) ;
94
94
95
95
//sort results if sorting isn't disabled or skip needs to be called
96
96
if ( ! _sortDisabled || _skip > 0 )
@@ -104,26 +104,26 @@ public FormatedList<T> Parse()
104
104
//Use query expression to return filtered paged list
105
105
//This is a best effort to avoid client evaluation whenever possible
106
106
//No good api to determine support for .ToString() on a type
107
- if ( _queriable . Provider is System . Linq . EnumerableQuery && hasFilterText )
107
+ if ( _queryable . Provider is System . Linq . EnumerableQuery && hasFilterText )
108
108
{
109
- resultQuery = _queriable . Where ( EnumerablFilter )
109
+ resultQuery = _queryable . Where ( EnumerablFilter )
110
110
. Skip ( _skip )
111
111
. Take ( _take ) ;
112
112
113
- list . recordsFiltered = _queriable . Count ( EnumerablFilter ) ;
113
+ list . recordsFiltered = _queryable . Count ( EnumerablFilter ) ;
114
114
}
115
115
else if ( hasFilterText )
116
116
{
117
117
var entityFilter = GenerateEntityFilter ( ) ;
118
- resultQuery = _queriable . Where ( entityFilter )
118
+ resultQuery = _queryable . Where ( entityFilter )
119
119
. Skip ( _skip )
120
120
. Take ( _take ) ;
121
121
122
- list . recordsFiltered = _queriable . Count ( entityFilter ) ;
122
+ list . recordsFiltered = _queryable . Count ( entityFilter ) ;
123
123
}
124
124
else
125
125
{
126
- resultQuery = _queriable
126
+ resultQuery = _queryable
127
127
. Skip ( _skip )
128
128
. Take ( _take ) ;
129
129
@@ -132,18 +132,15 @@ public FormatedList<T> Parse()
132
132
}
133
133
134
134
135
- list . data = resultQuery
136
- . ToList ( ) ;
137
-
138
- list . SetQuery ( resultQuery . ToString ( ) ) ;
135
+ list . data = resultQuery . ToList ( ) ;
139
136
140
137
return list ;
141
138
}
142
139
143
140
private void ApplySort ( )
144
141
{
145
142
var sorted = false ;
146
- var paramExpr = Expression . Parameter ( typeof ( T ) , "val" ) ;
143
+ var paramExpr = Expression . Parameter ( _type , "val" ) ;
147
144
148
145
// Enumerate the keys sort keys in the order we received them
149
146
foreach ( var param in _config . Where ( k => Regex . IsMatch ( k . Key , Constants . ORDER_PATTERN ) ) )
@@ -167,7 +164,7 @@ private void ApplySort()
167
164
var sortProperty = _propertyMap [ sortcolumn ] . Property ;
168
165
var expression1 = Expression . Property ( paramExpr , sortProperty ) ;
169
166
var propType = sortProperty . PropertyType ;
170
- var delegateType = Expression . GetFuncType ( typeof ( T ) , propType ) ;
167
+ var delegateType = Expression . GetFuncType ( _type , propType ) ;
171
168
var propertyExpr = Expression . Lambda ( delegateType , expression1 , paramExpr ) ;
172
169
173
170
// apply the sort (default is ascending if not specified)
@@ -181,13 +178,13 @@ private void ApplySort()
181
178
methodName = sorted ? "ThenByDescending" : "OrderByDescending" ;
182
179
}
183
180
184
- _queriable = typeof ( Queryable ) . GetMethods ( ) . Single (
181
+ _queryable = typeof ( Queryable ) . GetMethods ( ) . Single (
185
182
method => method . Name == methodName
186
183
&& method . IsGenericMethodDefinition
187
184
&& method . GetGenericArguments ( ) . Length == 2
188
185
&& method . GetParameters ( ) . Length == 2 )
189
- . MakeGenericMethod ( typeof ( T ) , propType )
190
- . Invoke ( null , new object [ ] { _queriable , propertyExpr } ) as IOrderedQueryable < T > ;
186
+ . MakeGenericMethod ( _type , propType )
187
+ . Invoke ( null , new object [ ] { _queryable , propertyExpr } ) as IOrderedQueryable < T > ;
191
188
192
189
sorted = true ;
193
190
}
@@ -198,16 +195,16 @@ private void ApplySort()
198
195
{
199
196
var firstProp = Expression . Property ( paramExpr , _propertyMap . First ( ) . Value . Property ) ;
200
197
var propType = _propertyMap . First ( ) . Value . Property . PropertyType ;
201
- var delegateType = Expression . GetFuncType ( typeof ( T ) , propType ) ;
198
+ var delegateType = Expression . GetFuncType ( _type , propType ) ;
202
199
var propertyExpr = Expression . Lambda ( delegateType , firstProp , paramExpr ) ;
203
200
204
- _queriable = typeof ( Queryable ) . GetMethods ( ) . Single (
201
+ _queryable = typeof ( Queryable ) . GetMethods ( ) . Single (
205
202
method => method . Name == "OrderBy"
206
203
&& method . IsGenericMethodDefinition
207
204
&& method . GetGenericArguments ( ) . Length == 2
208
205
&& method . GetParameters ( ) . Length == 2 )
209
- . MakeGenericMethod ( typeof ( T ) , propType )
210
- . Invoke ( null , new object [ ] { _queriable , propertyExpr } ) as IOrderedQueryable < T > ;
206
+ . MakeGenericMethod ( _type , propType )
207
+ . Invoke ( null , new object [ ] { _queryable , propertyExpr } ) as IOrderedQueryable < T > ;
211
208
212
209
}
213
210
@@ -232,7 +229,7 @@ private bool EnumerablFilter(T item)
232
229
}
233
230
234
231
/// <summary>
235
- /// Expression for an all column search, which will filter the result based on this criterion
232
+ /// Generate a lamda expression based on a search filter for all mapped columns
236
233
/// </summary>
237
234
private Expression < Func < T , bool > > GenerateEntityFilter ( )
238
235
{
@@ -241,23 +238,23 @@ private Expression<Func<T, bool>> GenerateEntityFilter()
241
238
242
239
// invariant expressions
243
240
var searchExpression = Expression . Constant ( search . ToLower ( ) ) ;
244
- var paramExpression = Expression . Parameter ( typeof ( T ) , "val" ) ;
241
+ var paramExpression = Expression . Parameter ( _type , "val" ) ;
245
242
List < MethodCallExpression > searchProps = new List < MethodCallExpression > ( ) ;
246
243
247
244
foreach ( var propMap in _propertyMap )
248
245
{
249
- var property = propMap . Value . Property ;
250
- var isString = property . PropertyType == typeof ( string ) ;
251
- if ( ! property . CanWrite || ! propMap . Value . Searchable || ( ! _convertable . Any ( t => t == property . PropertyType ) && ! isString ) )
246
+ var prop = propMap . Value . Property ;
247
+ var isString = prop . PropertyType == typeof ( string ) ;
248
+ if ( ! prop . CanWrite || ! propMap . Value . Searchable || ( ! _convertable . Any ( t => t == prop . PropertyType ) && ! isString ) )
252
249
{
253
250
continue ;
254
251
}
255
252
256
- Expression propExp = Expression . Property ( paramExpression , property ) ;
253
+ Expression propExp = Expression . Property ( paramExpression , prop ) ;
257
254
258
255
if ( ! isString )
259
256
{
260
- var toString = property . PropertyType . GetMethod ( "ToString" , Type . EmptyTypes ) ;
257
+ var toString = prop . PropertyType . GetMethod ( "ToString" , Type . EmptyTypes ) ;
261
258
262
259
propExp = Expression . Call ( propExp , toString ) ;
263
260
@@ -280,14 +277,14 @@ private Expression<Func<T, bool>> GenerateEntityFilter()
280
277
compoundExpression = Expression . Or ( compoundExpression , propertyQuery [ i ] ) ;
281
278
}
282
279
283
- // compile the expression into a lambda
280
+ // return the expression into a lambda
284
281
return Expression . Lambda < Func < T , bool > > ( compoundExpression , paramExpression ) ;
285
282
286
283
}
287
284
288
285
289
286
290
- private class PropertyMapping
287
+ private class PropertyMap
291
288
{
292
289
public PropertyInfo Property { get ; set ; }
293
290
public bool Orderable { get ; set ; }
@@ -299,20 +296,8 @@ private class PropertyMapping
299
296
300
297
301
298
}
302
- public class FormatedList < T >
299
+ public class Results < T >
303
300
{
304
- private string _query ;
305
-
306
- internal void SetQuery ( string query )
307
- {
308
- _query = query ;
309
- }
310
-
311
- public string GetQuery ( )
312
- {
313
- return _query ;
314
- }
315
-
316
301
public int draw { get ; set ; }
317
302
public int recordsTotal { get ; set ; }
318
303
public int recordsFiltered { get ; set ; }
0 commit comments