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())); }
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); }