private static Expression GetSearchExpressionForProp(ParameterExpression param, Expression x, string search) { ReplaceParameter visitor = new ReplaceParameter(); var pExpression = (x.NodeType == ExpressionType.Convert) ? visitor.Modify((x as UnaryExpression).Operand, param) : visitor.Modify(x, param); Type propType = pExpression.Type; if (propType.BaseType == typeof(Enum)) { var searchExpression = Expression.Constant(search.Trim().ToLower()); var toStringExpression = Expression.Call(pExpression, typeof(Enum).GetMethods().First(m => m.Name == "ToString")); var toLowerExpression = Expression.Call(toStringExpression, typeof(string).GetMethods().First(m => m.Name == "ToLower")); var pNotNullExpression = Expression.Constant(true);//Expression.NotEqual(pExpression, Expression.Constant(null)); var pContainsExpression = Expression.Call(toLowerExpression, typeof(string).GetMethod("Contains"), searchExpression); return(Expression.AndAlso(pContainsExpression, pNotNullExpression)); } if (propType == typeof(DateTime) || propType == typeof(DateTime?)) { return(BuildDateTimeExpression(x, param, search)); } if (propType == typeof(string)) { var searchExpression = Expression.Constant(search.Trim().ToLower()); var toLowerExpression = Expression.Call(pExpression, typeof(string).GetMethods().First(m => m.Name == "ToLower")); var pNotNullExpression = Expression.NotEqual(pExpression, Expression.Constant(null)); var pContainsExpression = Expression.Call(toLowerExpression, typeof(string).GetMethod("Contains"), searchExpression); return(Expression.IsTrue(pContainsExpression)); } else { try { object converted = null; if (Nullable.GetUnderlyingType(propType) != null) { converted = Convert.ChangeType(search.ToLower(), Nullable.GetUnderlyingType(propType)); return(Expression.AndAlso(Expression.NotEqual(pExpression, Expression.Constant(null)), Expression.Equal(Expression.Property(pExpression, "Value"), Expression.Constant(converted)))); } else { converted = Convert.ChangeType(search.ToLower(), propType); return(Expression.Equal(pExpression, Expression.Constant(converted))); } } catch { return(Expression.Constant(false)); } } }
private static IQueryable <T> ApplyDataTablesSortImp <T>(this IQueryable <T> source, NameValueCollection request, int?count = 0) { request = GetRequest(request); if (request == null) { return(source); } string key = RequestKey <T>(request); Expression <Func <T, object> >[] orderbys = null; try { orderbys = (Expression <Func <T, object> >[])RequestDTOrderBys[key]; } catch { try { orderbys = (Expression <Func <T, object> >[])RequestDTSelects[key]; } catch { } } PropertyInfo[] _properties = typeof(T).GetProperties(); // enumerate the keys for any sortations foreach (string iSortKey in request.AllKeys.Where(x => x.StartsWith(DataTablesConst.INDIVIDUAL_SORT_KEY_PREFIX))) { // column number to sort (same as the array) int sortcolumn = int.Parse(request[iSortKey]); // ignore malformatted values if (sortcolumn < 0 || sortcolumn >= _properties.Length) { continue; } // get the direction of the sort string sortdir = request[DataTablesConst.INDIVIDUAL_SORT_DIRECTION_KEY_PREFIX + iSortKey.Replace(DataTablesConst.INDIVIDUAL_SORT_KEY_PREFIX, string.Empty)]; var param = Expression.Parameter(typeof(T), "val"); Expression pExpression; if (orderbys != null && orderbys.Count() > sortcolumn) { Expression x = orderbys[sortcolumn].Body; ReplaceParameter visitor = new ReplaceParameter(); pExpression = (x.NodeType == ExpressionType.Convert) ? visitor.Modify((x as UnaryExpression).Operand, param) : visitor.Modify(x, param); } else { pExpression = Expression.MakeMemberAccess(param, _properties[sortcolumn]); } Type propType = pExpression.Type; var orderByExp = Expression.Lambda(pExpression, param); MethodCallExpression resultExp; if (string.IsNullOrEmpty(sortdir) || sortdir.Equals(DataTablesConst.ASCENDING_SORT, StringComparison.OrdinalIgnoreCase)) { resultExp = Expression.Call(typeof(Queryable), "OrderBy", new Type[] { typeof(T), propType }, source.Expression, Expression.Quote(orderByExp)); } else { resultExp = Expression.Call(typeof(Queryable), "OrderByDescending", new Type[] { typeof(T), propType }, source.Expression, Expression.Quote(orderByExp)); } source = source.Provider.CreateQuery <T>(resultExp); } return(source); }
private static Expression BuildDateTimeExpression(Expression x, ParameterExpression param, string search) { ReplaceParameter visitor = new ReplaceParameter(); var pExpression = (x.NodeType == ExpressionType.Convert) ? visitor.Modify((x as UnaryExpression).Operand, param) : visitor.Modify(x, param); Type propType = pExpression.Type; try { DateTime converted; bool bDateTime = DateTime.TryParse(search, out converted); if (bDateTime) { if (propType == typeof(DateTime?)) { Expression notNull = Expression.NotEqual(pExpression, Expression.Constant(null)); Expression equal = Expression.Equal(Expression.Property(pExpression, "Value"), Expression.Constant(converted)); MethodInfo miTruncateTime = typeof(DbFunctions).GetMethods().First(m => m.Name == "TruncateTime" && m.GetParameters().First().ParameterType == typeof(DateTime?)); Expression dateEqual = Expression.Equal(Expression.Call(null, miTruncateTime, pExpression), Expression.Convert(Expression.Constant(converted.Date), typeof(DateTime?))); Expression exp; exp = Expression.AndAlso(notNull, equal); exp = Expression.Or(exp, Expression.AndAlso(notNull, dateEqual)); return(exp); } else { Expression equal = Expression.Equal(pExpression, Expression.Constant(converted)); MethodInfo miTruncateTime = typeof(DbFunctions).GetMethods().First(m => m.Name == "TruncateTime" && m.GetParameters().First().ParameterType == typeof(DateTime?)); Expression dateEqual = Expression.Equal(Expression.Call(null, miTruncateTime, Expression.Convert(pExpression, typeof(DateTime?))), Expression.Constant(converted.Date)); Expression exp; exp = equal; exp = Expression.Or(exp, dateEqual); return(exp); } } int datePart; bool bDatePart = int.TryParse(search, out datePart); if (bDatePart) { if (propType == typeof(DateTime?)) { Expression notNull = Expression.NotEqual(pExpression, Expression.Constant(null)); Expression yearEqual = Expression.Equal(Expression.Property(Expression.Property(pExpression, "Value"), "Year"), Expression.Constant(datePart)); Expression monthEqual = Expression.Equal(Expression.Property(Expression.Property(pExpression, "Value"), "Month"), Expression.Constant(datePart)); Expression exp; exp = Expression.AndAlso(notNull, yearEqual); exp = Expression.Or(exp, Expression.AndAlso(notNull, monthEqual)); return(exp); } else { Expression yearEqual = Expression.Equal(Expression.Property(pExpression, "Year"), Expression.Constant(datePart)); Expression monthEqual = Expression.Equal(Expression.Property(pExpression, "Month"), Expression.Constant(datePart)); Expression exp; exp = yearEqual; exp = Expression.Or(exp, monthEqual); return(exp); } } int day = -1; string[] days = Enum.GetNames(typeof(DayOfWeek)); for (int i = 0; i < days.Length; i++) { if (days[i].ToLower() == search.Trim().ToLower()) { day = i + 1; } } if (day > -1) { if (propType == typeof(DateTime?)) { Expression notNull = Expression.NotEqual(pExpression, Expression.Constant(null)); MethodInfo miSqlDatePart = typeof(SqlFunctions).GetMethods().First(m => m.Name == "DatePart" && m.GetParameters()[1].ParameterType == typeof(DateTime?)); Expression dayEqual = Expression.Equal(Expression.Property(Expression.Call(null, miSqlDatePart, Expression.Constant("weekday"), pExpression), "Value"), Expression.Constant(day)); return(Expression.AndAlso(notNull, dayEqual)); } else { MethodInfo miSqlDatePart = typeof(SqlFunctions).GetMethods().First(m => m.Name == "DatePart" && m.GetParameters()[1].ParameterType == typeof(DateTime?)); Expression dayEqual = Expression.Equal(Expression.Property(Expression.Call(null, miSqlDatePart, Expression.Constant("weekday"), Expression.Convert(pExpression, typeof(DateTime?))), "Value"), Expression.Constant(day)); return(dayEqual); } } return(Expression.Constant(false)); } catch { return(Expression.Constant(false)); } }