Esempio n. 1
0
        private object ResolveProjection(ParameterBuilder builder, LambdaExpression lambdaExpression, Type sourceType)
        {
            Contract.Requires(lambdaExpression != null);

            var selectFunction = lambdaExpression.Body as NewExpression;

            if (selectFunction != null)
            {
                var properties = sourceType.GetProperties();
                var members    = selectFunction.Members
                                 .Select(x => properties.FirstOrDefault(y => y.Name == x.Name) ?? x)
                                 .Select(x => _memberNameResolver.ResolveName(x))
                                 .ToArray();
                var args = selectFunction.Arguments.OfType <MemberExpression>()
                           .Select(x => properties.FirstOrDefault(y => y.Name == x.Member.Name) ?? x.Member)
                           .Select(x => _memberNameResolver.ResolveName(x))
                           .ToArray();
                if (members.Intersect(args).Count() != members.Length)
                {
                    throw new InvalidOperationException("Projection into new member names is not supported.");
                }

                builder.SelectParameter = string.Join(",", args);
            }

            var propertyExpression = lambdaExpression.Body as MemberExpression;

            if (propertyExpression != null)
            {
                builder.SelectParameter = string.IsNullOrWhiteSpace(builder.SelectParameter)
                                        ? _memberNameResolver.ResolveName(propertyExpression.Member)
                                        : builder.SelectParameter + "," + _memberNameResolver.ResolveName(propertyExpression.Member);
            }

            return(null);
        }
Esempio n. 2
0
        public object ProcessMethodCall <T>(MethodCallExpression methodCall, ParameterBuilder builder, Func <ParameterBuilder, IEnumerable <T> > resultLoader, Func <Type, ParameterBuilder, IEnumerable> intermediateResultLoader)
        {
            if (methodCall == null)
            {
                return(null);
            }

            var method = methodCall.Method.Name;

            switch (method)
            {
            case "First":
            case "FirstOrDefault":
                builder.TakeParameter = "1";
                return(methodCall.Arguments.Count >= 2
                                                                ? GetMethodResult(methodCall, builder, resultLoader, intermediateResultLoader)
                                                                : GetResult(methodCall, builder, resultLoader, intermediateResultLoader));

            case "Single":
            case "SingleOrDefault":
            case "Last":
            case "LastOrDefault":
            case "Count":
            case "LongCount":
                return(methodCall.Arguments.Count >= 2
                                                        ? GetMethodResult(methodCall, builder, resultLoader, intermediateResultLoader)
                                                        : GetResult(methodCall, builder, resultLoader, intermediateResultLoader));

            case "Where":
                Contract.Assume(methodCall.Arguments.Count >= 2);
                {
                    var result = ProcessMethodCall(methodCall.Arguments[0] as MethodCallExpression, builder, resultLoader, intermediateResultLoader);
                    if (result != null)
                    {
                        return(InvokeEager(methodCall, result));
                    }

                    var newFilter = _writer.Write(methodCall.Arguments[1], builder.SourceType);

                    builder.FilterParameter = string.IsNullOrWhiteSpace(builder.FilterParameter)
                                                                                                        ? newFilter
                                                                                                        : string.Format("({0}) and ({1})", builder.FilterParameter, newFilter);
                }

                break;

            case "Select":
                Contract.Assume(methodCall.Arguments.Count >= 2);
                {
                    var result = ProcessMethodCall(methodCall.Arguments[0] as MethodCallExpression, builder, resultLoader, intermediateResultLoader);
                    if (result != null)
                    {
                        return(InvokeEager(methodCall, result));
                    }

                    if (!string.IsNullOrWhiteSpace(builder.SelectParameter))
                    {
                        return(ExecuteMethod(methodCall, builder, resultLoader, intermediateResultLoader));
                    }

                    var unaryExpression = methodCall.Arguments[1] as UnaryExpression;
                    if (unaryExpression != null)
                    {
                        var lambdaExpression = unaryExpression.Operand as LambdaExpression;
                        if (lambdaExpression != null)
                        {
                            var sourceType = builder.SourceType;
                            return(ResolveProjection(builder, lambdaExpression, sourceType));
                        }
                    }
                }

                break;

            case "OrderBy":
            case "ThenBy":
                Contract.Assume(methodCall.Arguments.Count >= 2);
                {
                    var methodCallExpression = methodCall.Arguments[0] as MethodCallExpression;
                    var result = ProcessMethodCall(methodCallExpression, builder, resultLoader, intermediateResultLoader);
                    if (result != null)
                    {
                        return(InvokeEager(methodCall, result));
                    }

                    var sourceType   = builder.SourceType;
                    var sortProperty = methodCall.Arguments[1];
                    var item         = _writer.Write(sortProperty, sourceType);
                    builder.OrderByParameter.Add(item);
                }

                break;

            case "OrderByDescending":
            case "ThenByDescending":
                Contract.Assume(methodCall.Arguments.Count >= 2);
                {
                    var result = ProcessMethodCall(methodCall.Arguments[0] as MethodCallExpression, builder, resultLoader, intermediateResultLoader);
                    if (result != null)
                    {
                        return(InvokeEager(methodCall, result));
                    }

                    var visit = _writer.Write(methodCall.Arguments[1], builder.SourceType);
                    builder.OrderByParameter.Add(visit + " desc");
                }

                break;

            case "Take":
                Contract.Assume(methodCall.Arguments.Count >= 2);
                {
                    var result = ProcessMethodCall(methodCall.Arguments[0] as MethodCallExpression, builder, resultLoader, intermediateResultLoader);
                    if (result != null)
                    {
                        return(InvokeEager(methodCall, result));
                    }

                    builder.TakeParameter = _writer.Write(methodCall.Arguments[1], builder.SourceType);
                }

                break;

            case "Skip":
                Contract.Assume(methodCall.Arguments.Count >= 2);
                {
                    var result = ProcessMethodCall(methodCall.Arguments[0] as MethodCallExpression, builder, resultLoader, intermediateResultLoader);
                    if (result != null)
                    {
                        return(InvokeEager(methodCall, result));
                    }

                    builder.SkipParameter = _writer.Write(methodCall.Arguments[1], builder.SourceType);
                }

                break;

            case "Expand":
                Contract.Assume(methodCall.Arguments.Count >= 2);
                {
                    var result = ProcessMethodCall(methodCall.Arguments[0] as MethodCallExpression, builder, resultLoader, intermediateResultLoader);
                    if (result != null)
                    {
                        return(InvokeEager(methodCall, result));
                    }

                    var expression = methodCall.Arguments[1];

                    Contract.Assume(expression != null);

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

                    builder.ExpandParameter = getterLambda().ToString();
                }

                break;

            default:
                return(ExecuteMethod(methodCall, builder, resultLoader, intermediateResultLoader));
            }

            return(null);
        }
Esempio n. 3
0
 protected abstract IEnumerable GetIntermediateResults(Type type, ParameterBuilder builder);
Esempio n. 4
0
        protected override IEnumerable GetIntermediateResults(Type type, ParameterBuilder builder)
        {
            CustomContract.Requires(builder != null);

            throw new NotImplementedException();
        }
Esempio n. 5
0
 protected abstract IEnumerable <T> GetResults(ParameterBuilder builder);