public static IQueryable <T> Where <T>(this IQueryable <T> query, string column, object value, WhereOperation operation) { if (string.IsNullOrEmpty(column)) { return(query); } ParameterExpression parameter = Expression.Parameter(query.ElementType, "p"); MemberExpression memberAccess = null; foreach (var property in column.Split(' ')) { memberAccess = MemberExpression.Property (memberAccess ?? (parameter as Expression), property); } Type type = memberAccess.Type; Expression condition = null; LambdaExpression lambda = null; //Expression[] lambdaArr = new Expression[2]; if (string.IsNullOrEmpty(value.ToString())) { value = GetDefault(type); } //if (type == typeof (int)) value = 0; else { //change param value type //necessary to getting bool from string if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) { type = memberAccess.Type.GetGenericArguments()[0]; } if (type.IsEnum) { value = StringEnum.GetEnum(type, value.ToString()); } else if (type == typeof(DateTimeOffset)) { string time = string.Empty; if (operation == WhereOperation.Less || operation == WhereOperation.GreaterOrEqual) { time = " 00:00:01+00:00"; } if (operation == WhereOperation.Greater || operation == WhereOperation.LessOrEqual) { time = " 23:59:59+00:00"; } if (operation == WhereOperation.Equal) { var from = DateTimeOffset.Parse(String.Format("{0}{1}", value, " 00:00:01 +00:00"), CultureInfo.InvariantCulture); ConstantExpression filterFrom = Expression.Constant(from, memberAccess.Type); var to = DateTimeOffset.Parse(String.Format("{0}{1}", value, " 23:59:59 +00:00"), CultureInfo.InvariantCulture); ConstantExpression filterTo = Expression.Constant(to, memberAccess.Type); var condition1 = Expression.GreaterThan(memberAccess, filterFrom); var condition2 = Expression.LessThan(memberAccess, filterTo); var body = Expression.AndAlso(condition1, condition2); lambda = Expression.Lambda <Func <T, bool> >(body, parameter); } else { value = DateTimeOffset.Parse(String.Format("{0}{1}", value, time), CultureInfo.InvariantCulture); } } else if (type == typeof(decimal)) { value = Convert.ChangeType(value, type); if (operation == WhereOperation.Equal) { ConstantExpression filter1 = Expression.Constant((decimal)value - 0.01M, memberAccess.Type); ConstantExpression filter2 = Expression.Constant((decimal)value + 0.01M, memberAccess.Type); var condition1 = Expression.GreaterThan(memberAccess, filter1); var condition2 = Expression.LessThan(memberAccess, filter2); var body = Expression.AndAlso(condition1, condition2); lambda = Expression.Lambda <Func <T, bool> >(body, parameter); } else if (operation == WhereOperation.NotEqual) { ConstantExpression filter = Expression.Constant(value, memberAccess.Type); var condition1 = Expression.LessThan(memberAccess, filter); var condition2 = Expression.GreaterThan(memberAccess, filter); var body = Expression.OrElse(condition1, condition2); lambda = Expression.Lambda <Func <T, bool> >(body, parameter); } } else { value = Convert.ChangeType(value, type); } } if (lambda == null) { //ConstantExpression filter = Expression.Constant(value == null ? value : Convert.ChangeType(value, memberAccess.Type)); ConstantExpression filter = Expression.Constant(value, memberAccess.Type); //ConstantExpression filter = Expression.Constant(value); //switch operation switch (operation) { //equal == case WhereOperation.Equal: case WhereOperation.IsNull: condition = Expression.Equal(memberAccess, filter); lambda = Expression.Lambda(condition, parameter); break; //not equal != case WhereOperation.NotEqual: case WhereOperation.IsNotNull: condition = Expression.NotEqual(memberAccess, filter); lambda = Expression.Lambda(condition, parameter); break; //string.Contains() case WhereOperation.Contains: case WhereOperation.BeginsWith: condition = Expression.Call(memberAccess, typeof(string).GetMethod("Contains"), Expression.Constant(value)); lambda = value is string ?Expression.Lambda(condition, parameter) : Expression.Lambda <Func <T, bool> >(condition, parameter); break; case WhereOperation.Greater: condition = Expression.GreaterThan(memberAccess, filter); lambda = Expression.Lambda(condition, parameter); break; case WhereOperation.GreaterOrEqual: condition = Expression.GreaterThanOrEqual(memberAccess, filter); lambda = Expression.Lambda(condition, parameter); break; case WhereOperation.Less: condition = Expression.LessThan(memberAccess, filter); lambda = Expression.Lambda(condition, parameter); break; case WhereOperation.LessOrEqual: condition = Expression.LessThanOrEqual(memberAccess, filter); lambda = Expression.Lambda(condition, parameter); break; default: return(query); } } MethodCallExpression result = Expression.Call(typeof(Queryable), "Where", new[] { query.ElementType }, query.Expression, lambda); return(query.Provider.CreateQuery <T>(result)); }