Ejemplo n.º 1
0
        private static ODataExpression ParseMemberExpression(Expression expression, string memberNames = null)
        {
            var memberExpression = expression as MemberExpression;

            if (memberExpression.Expression == null)
            {
                return(new ODataExpression(EvaluateStaticMember(memberExpression)));
            }
            else
            {
                var memberName = memberExpression.Member.GetMappedName();
                memberNames = memberNames == null ? memberName : string.Join(".", memberName, memberNames);
                switch (memberExpression.Expression.NodeType)
                {
                case ExpressionType.Parameter:
                    return(FromReference(memberNames));

                case ExpressionType.Constant:
                    return(ParseConstantExpression(memberExpression.Expression, memberNames));

                case ExpressionType.MemberAccess:
                    if (FunctionMapping.ContainsFunction(memberName, 0))
                    {
                        return(FromFunction(memberName, ParseMemberExpression(memberExpression.Expression), new List <object>()));
                    }
                    else
                    {
                        return(ParseMemberExpression(memberExpression.Expression as MemberExpression, memberNames));
                    }

                default:
                    throw Utils.NotSupportedExpression(expression);
                }
            }
        }
Ejemplo n.º 2
0
            public override DynamicMetaObject BindInvokeMember(
                InvokeMemberBinder binder, DynamicMetaObject[] args)
            {
                if (FunctionMapping.ContainsFunction(binder.Name, args.Count()))
                {
                    var expression = Expression.New(CtorWithExpressionAndExpressionFunction,
                                                    new[]
                    {
                        Expression.Constant(this.Value),
                        Expression.Constant(new ExpressionFunction(binder.Name, args.Select(x => x.Value)))
                    });

                    return(new DynamicMetaObject(
                               expression,
                               BindingRestrictions.GetTypeRestriction(Expression, LimitType)));
                }
                else if (string.Equals(binder.Name, ODataLiteral.Any, StringComparison.OrdinalIgnoreCase) ||
                         string.Equals(binder.Name, ODataLiteral.All, StringComparison.OrdinalIgnoreCase))
                {
                    var expression = Expression.New(CtorWithExpressionAndExpressionFunction,
                                                    new[]
                    {
                        Expression.Constant(this.Value),
                        Expression.Constant(new ExpressionFunction(binder.Name, args.Select(x => x.Value)))
                    });

                    return(new DynamicMetaObject(
                               expression,
                               BindingRestrictions.GetTypeRestriction(Expression, LimitType)));
                }
                else
                {
                    return(base.BindInvokeMember(binder, args));
                }
            }
Ejemplo n.º 3
0
            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));
            }
        private IEnumerable <string> BuildReferencePath(List <string> segmentNames, EntityCollection entityCollection, List <string> elementNames, ExpressionContext context)
        {
            if (!elementNames.Any())
            {
                return(segmentNames);
            }

            var objectName = elementNames.First();

            if (entityCollection != null)
            {
                if (context.Session.Metadata.HasStructuralProperty(entityCollection.Name, objectName))
                {
                    var propertyName = context.Session.Metadata.GetStructuralPropertyExactName(
                        entityCollection.Name, objectName);
                    segmentNames.Add(propertyName);
                    return(BuildReferencePath(segmentNames, null, elementNames.Skip(1).ToList(), context));
                }
                else if (context.Session.Metadata.HasNavigationProperty(entityCollection.Name, objectName))
                {
                    var propertyName = context.Session.Metadata.GetNavigationPropertyExactName(
                        entityCollection.Name, objectName);
                    var linkName = context.Session.Metadata.GetNavigationPropertyPartnerTypeName(
                        entityCollection.Name, objectName);
                    var linkedEntityCollection = context.Session.Metadata.GetEntityCollection(linkName);
                    segmentNames.Add(propertyName);
                    return(BuildReferencePath(segmentNames, linkedEntityCollection, elementNames.Skip(1).ToList(), context));
                }
                else if (IsFunction(objectName, context))
                {
                    var formattedFunction = FormatAsFunction(objectName, context);
                    segmentNames.Add(formattedFunction);
                    return(BuildReferencePath(segmentNames, null, elementNames.Skip(1).ToList(), context));
                }
                else if (context.Session.Metadata.IsOpenType(entityCollection.Name))
                {
                    segmentNames.Add(objectName);
                    return(BuildReferencePath(segmentNames, null, elementNames.Skip(1).ToList(), context));
                }
                else
                {
                    throw new UnresolvableObjectException(objectName, $"Invalid referenced object [{objectName}]");
                }
            }
            else if (FunctionMapping.ContainsFunction(elementNames.First(), 0))
            {
                var formattedFunction = FormatAsFunction(objectName, context);
                segmentNames.Add(formattedFunction);
                return(BuildReferencePath(segmentNames, null, elementNames.Skip(1).ToList(), context));
            }
            else
            {
                segmentNames.AddRange(elementNames);
                return(BuildReferencePath(segmentNames, null, new List <string>(), context));
            }
        }
        private static ODataExpression ParseMemberExpression(Expression expression, Stack <MemberInfo> memberChain = null)
        {
            var memberExpression = expression as MemberExpression;

            if (memberExpression.Expression == null)
            {
                return(new ODataExpression(EvaluateStaticMember(memberExpression)));
            }
            else
            {
                memberChain ??= new Stack <MemberInfo>();
                memberChain.Push(memberExpression.Member);
                switch (memberExpression.Expression.NodeType)
                {
                case ExpressionType.Parameter:
                    // NOTE: Can't support ITypeCache here as we might be dealing with dynamic types/expressions
                    var memberNames = string.Join(".", memberChain.Select(x => x.GetMappedName()));
                    return(FromReference(memberNames));

                case ExpressionType.Constant:
                    return(ParseConstantExpression(memberExpression.Expression, memberChain));

                case ExpressionType.MemberAccess:
                    // NOTE: Can't support ITypeCache here as we might be dealing with dynamic types/expressions
                    var memberName = memberExpression.Member.GetMappedName();
                    if (FunctionMapping.ContainsFunction(memberName, 0))
                    {
                        return(FromFunction(memberName, ParseMemberExpression(memberExpression.Expression), new List <object>()));
                    }
                    else
                    {
                        return(ParseMemberExpression(memberExpression.Expression as MemberExpression, memberChain));
                    }

                default:
                    throw Utils.NotSupportedExpression(expression);
                }
            }
        }
Ejemplo n.º 6
0
            public override DynamicMetaObject BindGetMember(GetMemberBinder binder)
            {
                ConstructorInfo ctor;

                Expression[] ctorArguments;
                if (FunctionMapping.ContainsFunction(binder.Name, 0))
                {
                    ctor          = CtorWithExpressionAndString;
                    ctorArguments = new[] { Expression.Constant(this.Value), Expression.Constant(binder.Name) };
                }
                else
                {
                    var reference = this.HasValue && !string.IsNullOrEmpty((this.Value as ODataExpression).Reference)
                        ? string.Join("/", (this.Value as ODataExpression).Reference, binder.Name)
                        : binder.Name;
                    ctor          = CtorWithString;
                    ctorArguments = new[] { Expression.Constant(reference) };
                }

                return(new DynamicMetaObject(
                           Expression.New(ctor, ctorArguments),
                           BindingRestrictions.GetTypeRestriction(Expression, LimitType)));
            }
Ejemplo n.º 7
0
            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)));
            }