public override DynamicMetaObject BindInvokeMember( InvokeMemberBinder binder, DynamicMetaObject[] args) { var expressionFunctionConstructor = typeof(ExpressionFunction).GetConstructor(new[] { typeof(string), typeof(IEnumerable<object>) }); if (FunctionMapping.ContainsFunction(binder.Name, args.Length)) { var expression = Expression.New(CtorWithExpressionAndExpressionFunction, Expression.Convert(Expression, LimitType), Expression.New(expressionFunctionConstructor, Expression.Constant(binder.Name), Expression.NewArrayInit(typeof(object), args.Select(x => Expression.Convert(x.Expression, typeof(object)))))); return new DynamicMetaObject( expression, BindingRestrictions.GetTypeRestriction(Expression, LimitType)); } if (string.Equals(binder.Name, ODataLiteral.Any, StringComparison.OrdinalIgnoreCase) || string.Equals(binder.Name, ODataLiteral.All, StringComparison.OrdinalIgnoreCase)) { var expression = Expression.New(CtorWithExpressionAndExpressionFunction, Expression.Convert(Expression, LimitType), Expression.New(expressionFunctionConstructor, Expression.Constant(binder.Name), Expression.NewArrayInit(typeof(object), args.Select(x => Expression.Convert(x.Expression, typeof(object)))))); return new DynamicMetaObject( expression, BindingRestrictions.GetTypeRestriction(Expression, LimitType)); } if (string.Equals(binder.Name, ODataLiteral.IsOf, StringComparison.OrdinalIgnoreCase) || string.Equals(binder.Name, ODataLiteral.Is, StringComparison.OrdinalIgnoreCase) || string.Equals(binder.Name, ODataLiteral.Cast, StringComparison.OrdinalIgnoreCase) || string.Equals(binder.Name, ODataLiteral.As, StringComparison.OrdinalIgnoreCase)) { var functionName = string.Equals(binder.Name, ODataLiteral.Is, StringComparison.OrdinalIgnoreCase) ? ODataLiteral.IsOf : string.Equals(binder.Name, ODataLiteral.As, StringComparison.OrdinalIgnoreCase) ? ODataLiteral.Cast : binder.Name; var isNullProperty = typeof(DynamicODataExpression).GetProperty(nameof(IsNull)); var expressionFunctionArguments = Expression.Condition(Expression.MakeMemberAccess(Expression.Convert(Expression, LimitType), isNullProperty), Expression.Convert(Expression, typeof(object)), Expression.Convert(args.First().Expression, typeof(object))); var expression = Expression.New(CtorWithExpressionAndExpressionFunction, Expression.Convert(Expression, LimitType), Expression.New(expressionFunctionConstructor, Expression.Constant(functionName), Expression.NewArrayInit(typeof(object), expressionFunctionArguments))); return new DynamicMetaObject( expression, BindingRestrictions.GetTypeRestriction(Expression, LimitType)); } return base.BindInvokeMember(binder, args); }
public override DynamicMetaObject BindGetMember(GetMemberBinder binder) { ConstructorInfo ctor; Expression[] ctorArguments; if (FunctionMapping.ContainsFunction(binder.Name, 0)) { ctor = CtorWithExpressionAndString; ctorArguments = new Expression[] { Expression.Convert(Expression, LimitType), Expression.Constant(binder.Name) }; } else { Expression<Func<bool, ODataExpression, string>> calculateReference = (hv, e) => hv && !string.IsNullOrEmpty(e.Reference) ? string.Join("/", e.Reference, binder.Name) : binder.Name; var referenceExpression = Expression.Invoke(calculateReference, Expression.Constant(HasValue), Expression.Convert(Expression, LimitType)); ctor = CtorWithString; ctorArguments = new Expression[] { referenceExpression }; } return new DynamicMetaObject( Expression.New(ctor, ctorArguments), BindingRestrictions.GetTypeRestriction(Expression, LimitType)); }