private static Expression GetExpression <T>(ParameterExpression param, FilterObject filter)
        {
            MemberExpression member = Expression.Property(param, filter.Column);
            //ConstantExpression constant = Expression.Constant(filter.Value);

            // NEW LOGIC to handle nullable Decimal and DateTime values
            UnaryExpression constant = null;

            if (member.Type == typeof(Decimal?))
            {
                constant = Expression.Convert(Expression.Constant(Decimal.Parse(filter.Value)), member.Type);
            }
            else if (member.Type == typeof(DateTime?))
            {
                constant = Expression.Convert(Expression.Constant(DateTime.Parse(filter.Value)), member.Type);
            }
            else
            {
                constant = Expression.Convert(Expression.Constant(filter.Value), member.Type);
            }


            switch (filter.Operator)
            {
            case FilterOperator.Equals:
                return(Expression.Equal(member, constant));

            case FilterOperator.GreaterThan:
                return(Expression.GreaterThan(member, constant));

            case FilterOperator.GreaterThanOrEqual:
                return(Expression.GreaterThanOrEqual(member, constant));

            case FilterOperator.LessThan:
                return(Expression.LessThan(member, constant));

            case FilterOperator.LessThanOrEqual:
                return(Expression.LessThanOrEqual(member, constant));

            case FilterOperator.Contains:
                return(Expression.Call(member, containsMethod, constant));

            case FilterOperator.StartsWith:
                return(Expression.Call(member, startsWithMethod, constant));

            case FilterOperator.EndsWith:
                return(Expression.Call(member, endsWithMethod, constant));

            case FilterOperator.NotEqual:
                return(Expression.Negate(Expression.Equal(member, constant)));
            }

            return(null);
        }
        private static BinaryExpression GetExpression <T> (ParameterExpression param, FilterObject filter1, FilterObject filter2)
        {
            Expression bin1 = GetExpression <T>(param, filter1);
            Expression bin2 = GetExpression <T>(param, filter2);

            return(Expression.AndAlso(bin1, bin2));
        }
        public static string GetWhereClause(FilterObject filterObj, Type valueType)
        {
            string whereClause = "true";

            if (valueType != typeof(DateTime))
            {
                switch (filterObj.Operator)
                {
                case FilterOperator.Contains:
                    if (valueType == typeof(string))
                    {
                        whereClause += string.Format(" {0} {1}.Contains(\"{2}\")", filterObj.Conjunction,
                                                     filterObj.Column, filterObj.Value);
                    }
                    break;

                case FilterOperator.GreaterThan:
                    if (valueType != typeof(string))
                    {
                        whereClause += string.Format(" {0} {1} > {2}", filterObj.Conjunction, filterObj.Column,
                                                     filterObj.Value);
                    }
                    break;

                case FilterOperator.GreaterThanOrEqual:
                    if (valueType != typeof(string))
                    {
                        whereClause += string.Format(" {0} {1} >= {2}", filterObj.Conjunction, filterObj.Column,
                                                     filterObj.Value);
                    }
                    break;

                case FilterOperator.LessThan:
                    if (valueType != typeof(string))
                    {
                        whereClause += string.Format(" {0} {1} < {2}", filterObj.Conjunction, filterObj.Column,
                                                     filterObj.Value);
                    }
                    break;

                case FilterOperator.LessThanOrEqual:
                    if (valueType != typeof(string))
                    {
                        whereClause += string.Format(" {0} {1} <= {2}", filterObj.Conjunction, filterObj.Column,
                                                     filterObj.Value);
                    }
                    break;

                case FilterOperator.StartsWith:
                    if (valueType != typeof(string))
                    {
                        whereClause += string.Format(" {0} {1}.StartsWith(\"{2}\")", filterObj.Conjunction,
                                                     filterObj.Column, filterObj.Value);
                    }
                    break;

                case FilterOperator.EndsWith:
                    if (valueType != typeof(string))
                    {
                        whereClause += string.Format(" {0} {1}.EndsWith(\"{2}\")", filterObj.Conjunction,
                                                     filterObj.Column, filterObj.Value);
                    }
                    break;

                case FilterOperator.Equals:

                    whereClause +=
                        string.Format(valueType == typeof(string) ? " {0} {1} == \"{2}\"" : " {0} {1} == {2}",
                                      filterObj.Conjunction, filterObj.Column, filterObj.Value);
                    break;

                case FilterOperator.NotEqual:

                    whereClause +=
                        string.Format(valueType == typeof(string) ? " {0} {1} != \"{2}\"" : " {0} {1} != {2}",
                                      filterObj.Conjunction, filterObj.Column, filterObj.Value);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            else
            {
                DateTime dt;
                DateTime.TryParse(filterObj.Value, out dt);

                switch (filterObj.Operator)
                {
                case FilterOperator.Contains:
                    break;

                case FilterOperator.GreaterThan:

                    whereClause += string.Format(" {0} {1} > DateTime(\"{2}\")", filterObj.Conjunction, filterObj.Column, dt);
                    break;

                case FilterOperator.GreaterThanOrEqual:

                    whereClause += string.Format(" {0} {1} >= DateTime(\"{2}\")", filterObj.Conjunction, filterObj.Column, dt);
                    break;

                case FilterOperator.LessThan:

                    whereClause += string.Format(" {0} {1} <  DateTime(\"{2}\")", filterObj.Conjunction, filterObj.Column, dt);
                    break;

                case FilterOperator.LessThanOrEqual:
                    whereClause += string.Format(" {0} {1} <=  DateTime(\"{2}\")", filterObj.Conjunction, filterObj.Column, dt);
                    break;

                case FilterOperator.StartsWith:
                    break;

                case FilterOperator.EndsWith:
                    break;

                case FilterOperator.Equals:
                    whereClause += string.Format(" {0} {1} ==  DateTime(\"{2}\")", filterObj.Conjunction, filterObj.Column, dt);
                    break;

                case FilterOperator.NotEqual:
                    whereClause += string.Format(" {0} {1} !=  DateTime(\"{2}\")", filterObj.Conjunction, filterObj.Column, dt);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
            return(whereClause);
        }