private BsonValue VisitValue(Expression expr)
        {
            // its a constant; Eg: "fixed string"
            if (expr is ConstantExpression)
            {
                var value = expr as ConstantExpression;

                return(_mapper.Serialize(value.Type, value.Value, 0));
            }
            if (expr is MemberExpression && _parameters.Count > 0)
            {
                var mExpr  = (MemberExpression)expr;
                var mValue = VisitValue(mExpr.Expression);
                var value  = mValue.AsDocument[mExpr.Member.Name];
                return(_mapper.Serialize(typeof(object), value, 0));
            }
            if (expr is ParameterExpression)
            {
                BsonValue result;
                if (_parameters.TryGetValue((ParameterExpression)expr, out result))
                {
                    return(result);
                }
            }

            // execute expression
            var objectMember = Expression.Convert(expr, typeof(object));
            var getterLambda = Expression.Lambda <Func <object> >(objectMember);
            var getter       = getterLambda.Compile();

            return(_mapper.Serialize(typeof(object), getter(), 0));
        }
        private BsonValue VisitValue(Expression expr, Expression left)
        {
            // check if left side is an enum and convert to string before return
            Func <Type, object, BsonValue> convert = (type, value) =>
            {
                var enumType = (left as UnaryExpression) == null ? null : (left as UnaryExpression).Operand.Type;

                if (enumType != null && enumType.GetTypeInfo().IsEnum)
                {
                    var str = Enum.GetName(enumType, value);
                    return(_mapper.Serialize(typeof(string), str, 0));
                }

                return(_mapper.Serialize(type, value, 0));
            };

            // its a constant; Eg: "fixed string"
            if (expr is ConstantExpression)
            {
                var value = (expr as ConstantExpression);

                return(convert(value.Type, value.Value));
            }
            else if (expr is MemberExpression && _parameters.Count > 0)
            {
                var mExpr  = (MemberExpression)expr;
                var mValue = this.VisitValue(mExpr.Expression, left);
                var value  = mValue.AsDocument[mExpr.Member.Name];

                return(convert(typeof(object), value));
            }
            else if (expr is ParameterExpression)
            {
                BsonValue result;
                if (_parameters.TryGetValue((ParameterExpression)expr, out result))
                {
                    return(result);
                }
            }

            // execute expression
            var objectMember = Expression.Convert(expr, typeof(object));
            var getterLambda = Expression.Lambda <Func <object> >(objectMember);
            var getter       = getterLambda.Compile();

            return(convert(typeof(object), getter()));
        }
Exemple #3
0
        private BsonValue VisitValue(Expression expr)
        {
            // its a constant; Eg: "fixed string"
            if (expr is ConstantExpression)
            {
                var value = (expr as ConstantExpression).Value;

                return(_mapper.Serialize(value));
            }

            // execute expression
            var objectMember = Expression.Convert(expr, typeof(object));
            var getterLambda = Expression.Lambda <Func <object> >(objectMember);
            var getter       = getterLambda.Compile();

            return(_mapper.Serialize(getter()));
        }
        /// <summary>
        /// Visit :: x => x.Age + `10` (will create parameter:  `p0`, `p1`, ...)
        /// </summary>
        protected override Expression VisitConstant(ConstantExpression node)
        {
            MemberExpression prevNode;
            var value = node.Value;

            // https://stackoverflow.com/a/29708655/3286260
            while (_nodes.Count > 0 && (prevNode = _nodes.Peek() as MemberExpression) != null)
            {
                if (prevNode.Member is FieldInfo fieldInfo)
                {
                    value = fieldInfo.GetValue(value);
                }
                else if (prevNode.Member is PropertyInfo propertyInfo)
                {
                    value = propertyInfo.GetValue(value);
                }

                _nodes.Pop();
            }

            ENSURE(_nodes.Count == 0, "counter stack must be zero to eval all properties/field over object");

            var parameter = "p" + (_paramIndex++);

            _builder.AppendFormat("@" + parameter);

            var type = value?.GetType();

            // if type is string, use direct BsonValue(string) to avoid rules like TrimWhitespace/EmptyStringToNull in mapper
            var arg = type == null ? BsonValue.Null :
                      type == typeof(string) ? new BsonValue((string)value) :
                      _mapper.Serialize(value.GetType(), value);

            _parameters[parameter] = arg;

            return(node);
        }