Skip to content

Commit 46dd2ac

Browse files
committed
Separate enumerable query fn no longer needed
1 parent 992adcb commit 46dd2ac

File tree

1 file changed

+17
-51
lines changed

1 file changed

+17
-51
lines changed

src/DatatablesParser/DatatablesParser.cs

Lines changed: 17 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace DataTablesParser
1010
{
1111
public class Parser<T> where T : class
1212
{
13-
private IQueryable<T> _queryable;
13+
private IQueryable<T> _query;
1414
private readonly Dictionary<string,string> _config;
1515
private readonly Type _type;
1616
private IDictionary<int, PropertyMap> _propertyMap ;
@@ -21,6 +21,7 @@ public class Parser<T> where T : class
2121
private bool _sortDisabled = false;
2222
private string _startsWithtoken = "*|";
2323
private string _endsWithToken = "|*";
24+
private bool _isEnumerableQuery;
2425

2526
private Dictionary<string,Expression> _converters = new Dictionary<string, Expression>();
2627

@@ -35,12 +36,13 @@ public class Parser<T> where T : class
3536
typeof(double),
3637
typeof(Nullable<double>),
3738
typeof(DateTime),
38-
typeof(Nullable<DateTime>)
39+
typeof(Nullable<DateTime>),
40+
typeof(string)
3941
};
4042

41-
public Parser(IEnumerable<KeyValuePair<string, StringValues>> configParams, IQueryable<T> queryable)
43+
public Parser(IEnumerable<KeyValuePair<string, StringValues>> configParams, IQueryable<T> query)
4244
{
43-
_queryable = queryable;
45+
_query = query;
4446
_config = configParams.ToDictionary(k => k.Key,v=> v.Value.First().Trim());
4547
_type = typeof(T);
4648

@@ -91,6 +93,7 @@ where Regex.IsMatch(param.Key,Constants.COLUMN_PROPERTY_PATTERN)
9193
}
9294

9395
_sortDisabled = _config.ContainsKey(Constants.ORDERING_ENABLED) && _config[Constants.ORDERING_ENABLED] == "false";
96+
_isEnumerableQuery = _query is System.Linq.EnumerableQuery;
9497
}
9598

9699
public Results<T> Parse()
@@ -101,7 +104,7 @@ public Results<T> Parse()
101104
list.draw = int.Parse(_config[Constants.DRAW]);
102105

103106
// count the record BEFORE filtering
104-
list.recordsTotal = _queryable.Count();
107+
list.recordsTotal = _query.Count();
105108

106109
//sort results if sorting isn't disabled or skip needs to be called
107110
if(!_sortDisabled || _skip > 0)
@@ -115,26 +118,18 @@ public Results<T> Parse()
115118
//Use query expression to return filtered paged list
116119
//This is a best effort to avoid client evaluation whenever possible
117120
//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)
127122
{
128123
var entityFilter = GenerateEntityFilter();
129-
resultQuery = _queryable.Where(entityFilter)
124+
resultQuery = _query.Where(entityFilter)
130125
.Skip(_skip)
131126
.Take(_take);
132127

133-
list.recordsFiltered = _queryable.Count(entityFilter);
128+
list.recordsFiltered = _query.Count(entityFilter);
134129
}
135130
else
136131
{
137-
resultQuery = _queryable
132+
resultQuery = _query
138133
.Skip(_skip)
139134
.Take(_take);
140135

@@ -238,13 +233,13 @@ private void ApplySort()
238233
methodName = sorted ? "ThenByDescending" : "OrderByDescending";
239234
}
240235

241-
_queryable = typeof(Queryable).GetMethods().Single(
236+
_query = typeof(Queryable).GetMethods().Single(
242237
method => method.Name == methodName
243238
&& method.IsGenericMethodDefinition
244239
&& method.GetGenericArguments().Length == 2
245240
&& method.GetParameters().Length == 2)
246241
.MakeGenericMethod(_type, propType)
247-
.Invoke(null, new object[] { _queryable, propertyExpr }) as IOrderedQueryable<T>;
242+
.Invoke(null, new object[] { _query, propertyExpr }) as IOrderedQueryable<T>;
248243

249244
sorted = true;
250245
}
@@ -258,47 +253,18 @@ private void ApplySort()
258253
var delegateType = Expression.GetFuncType(_type, propType);
259254
var propertyExpr = Expression.Lambda(delegateType, firstProp, paramExpr);
260255

261-
_queryable = typeof(Queryable).GetMethods().Single(
256+
_query = typeof(Queryable).GetMethods().Single(
262257
method => method.Name == "OrderBy"
263258
&& method.IsGenericMethodDefinition
264259
&& method.GetGenericArguments().Length == 2
265260
&& method.GetParameters().Length == 2)
266261
.MakeGenericMethod(_type, propType)
267-
.Invoke(null, new object[] { _queryable, propertyExpr }) as IOrderedQueryable<T>;
262+
.Invoke(null, new object[] { _query, propertyExpr }) as IOrderedQueryable<T>;
268263

269264
}
270265

271266
}
272267

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-
302268
private string GetFilterFn(string filter)
303269
{
304270
switch(filter)
@@ -344,7 +310,7 @@ private Expression<Func<T, bool>> GenerateEntityFilter()
344310
var hasCustomExpr = _converters.ContainsKey(prop.Name);
345311
string propFilterFn = null;
346312

347-
if ((!prop.CanWrite || (!_convertable.Any(t => t == prop.PropertyType) && !isString )) && !hasCustomExpr )
313+
if ( !prop.CanWrite || (!_convertable.Any(t => t == prop.PropertyType) && !hasCustomExpr && !_isEnumerableQuery ))
348314
{
349315
continue;
350316
}

0 commit comments

Comments
 (0)