Exemple #1
0
        private static void HandleSetOperation(Select select, MethodCallExpression expression, bool intersect, Func <IQueryable <T>, string> getTableName)
        {
            if (select.SetOperatons == null)
            {
                select.SetOperatons = new List <SetOperation>();
            }
            var setOperationSource = CreateModel(expression.ArgumentAt(2), getTableName).Select;

            setOperationSource.Top     = 1;
            setOperationSource.TopType = Select.TopValueType.Count;
            var operatorExpressions = expression.ArgumentAt <NewArrayExpression>(3).
                                      Expressions.
                                      Select(x => x.NodeType == ExpressionType.Quote ? ((UnaryExpression)x).Operand : x).
                                      Select(x => ((LambdaExpression)x).Body).
                                      Select(x => x.NodeType == ExpressionType.Convert ? ((UnaryExpression)x).Operand : x);
            var operators = operatorExpressions.Select(x => Operator.Create.Equal(Operand.Create.Projection(ProjectionVisitor <T> .CreateModel(x)),
                                                                                  Operand.Create.Projection(ProjectionVisitor <T> .CreateModel(x, select.From.Alias))));

            foreach (var @operator in operators)
            {
                setOperationSource.Where = setOperationSource.HasWhere ? Operator.Create.Operators(setOperationSource.Where, Operator.OperatorType.And, @operator) : @operator;
            }
            setOperationSource.Projection = operatorExpressions.Select(x => SelectProjection.Create(ProjectionVisitor <T> .CreateModel(x))).ToList();
            select.SetOperatons.Add(new SetOperation {
                Type   = intersect ? SetOperation.OperationType.Intersect : SetOperation.OperationType.Compliment,
                Select = setOperationSource
            });
        }
Exemple #2
0
        private static void HandleDuplicates(Select select, MethodCallExpression expression)
        {
            if (select.Duplicates == null)
            {
                select.Duplicates = new Duplicates();
            }
            select.Duplicates.Distinct = ProjectionVisitor <T> .CreateModel(expression.ArgumentAt(2));

            if (expression.Arguments.Count == 2)
            {
                select.Duplicates.OrderBy.Add(new OrderBy {
                    Type       = OrderBy.SourceType.Projection,
                    Projection = select.Duplicates.Distinct,
                    Order      = Order.Ascending
                });
            }
            else
            {
                Enumerable.Range(3, expression.Arguments.Count - 2)
                .Where(x => x % 2 == 1)
                .Select(x => new { Index = x, IsProjection = ProjectionVisitor <T> .IsProjection(expression.ArgumentAt(x).GetLambdaBody()) })
                .ToList().ForEach(x => select.Duplicates.OrderBy.Add(new OrderBy {
                    Type       = x.IsProjection ? OrderBy.SourceType.Projection : OrderBy.SourceType.Operator,
                    Projection = x.IsProjection ? ProjectionVisitor <T> .CreateModel(expression.ArgumentAt(x.Index)) : null,
                    Operator   = !x.IsProjection ? WhereVisitor <T> .CreateModel(expression.ArgumentAt(x.Index), select.From.Alias) : null,
                    Order      = expression.ConstantArgumentAt <Order>(x.Index + 1)
                }));
            }
        }
Exemple #3
0
 private static void HandleDistinct(Select select, MethodCallExpression expression)
 {
     if (select.Distinct == null)
     {
         select.Distinct = new List <Distinct>();
     }
     select.Distinct.Insert(0, new Distinct {
         Projection = ProjectionVisitor <T> .CreateModel(expression.ArgumentAt(2)),
         Order      = expression.HasArguments(4) ? new OrderBy {
             Type       = OrderBy.SourceType.Projection,
             Projection = ProjectionVisitor <T> .CreateModel(expression.ArgumentAt(3)),
             Order      = expression.ConstantArgumentAt <Order>(4)
         } : null
     });
 }
Exemple #4
0
 private static void HandleOrderBy(Select select, MethodCallExpression expression, bool descending)
 {
     if (select.OrderBy == null)
     {
         select.OrderBy = new List <OrderBy>();
     }
     select.OrderBy.Insert(0, new OrderBy {
         Order      = descending ? Order.Descending : Order.Ascending,
         Projection = ProjectionVisitor <T> .CreateModel(expression.ArgumentAt(2)),
         Type       = OrderBy.SourceType.Projection
     });
 }
Exemple #5
0
        private void HandleSync(Query target, MethodCallExpression expression)
        {
            target.Operation = Query.OperationType.SyncWith;
            var fields  = expression.ArgumentAt <NewArrayExpression>(5).Expressions.Select(x => x.GetLambdaBody().StripConversion());
            var exclude = expression.ConstantArgumentAt <SyncFields>(4) == SyncFields.Exclude;
            var source  = CreateModel(expression.ArgumentAt(2), _getTableName).Select;

            if (!exclude)
            {
                source.Projection = fields.Select(x => new SelectProjection {
                    Projection = ProjectionVisitor <T> .CreateModel(x, source.From.Alias)
                }).ToList();
                target.Select.Projection = fields.Select(x => new SelectProjection {
                    Projection = ProjectionVisitor <T> .CreateModel(x, target.Select.From.Alias)
                }).ToList();
            }
            target.SyncWith = new Sync {
                Target         = target.Select,
                Source         = source,
                SourceKey      = ProjectionVisitor <T> .CreateModel(expression.ArgumentAt(3), source.From.Alias),
                TargetKey      = ProjectionVisitor <T> .CreateModel(expression.ArgumentAt(3), target.Select.From.Alias),
                ExcludedFields = exclude ? fields.Select(x => ProjectionVisitor <T> .CreateModel(x).Field).ToList() : new List <Field>()
            };
        }
Exemple #6
0
        private static void HandleWhere(Select select, MethodCallExpression expression)
        {
            var where = WhereVisitor <T> .CreateModel(expression.ArgumentAt(2), select.From.Alias);

            if (!select.HasWhere)
            {
                select.Where = where;
            }
            else
            {
                var @operator = Operator.Create.ByType(Operator.OperatorType.And);
                @operator.LeftOperand  = Operand.Create.Operator(select.Where);
                @operator.RightOperand = Operand.Create.Operator(where);
                select.Where           = @operator;
            }
        }
Exemple #7
0
        protected override void VisitMethodCall(Context context, MethodCallExpression node)
        {
            var query = context.State;

            if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Union(Enumerable.Empty <T>())))
            {
                AddSourceQuery(query.Select, CreateModel(node.ArgumentAt(2), _getTableName).Select);
            }
            else if (query.Select.From.HasQueries)
            {
                // If we have unions we need to nest subsequent query operators otherwise they would apply to the
                // net result of the union. This is consistent with the behavior of linq to objects.
                AddSourceQuery(query.Select, CreateModel(node, _getTableName).Select);
                return;
            }
            else
            {
                if (node.MatchesMethodSignature <IQueryable <T> >(x => x.CopyTo(Queryable.Empty <T>())))
                {
                    HandleSelectInto(query, node);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Where(y => true)))
                {
                    HandleWhere(query.Select, node);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Distinct(y => y)))
                {
                    HandleDistinct(query.Select, node);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Distinct(y => y, y => y, Order.Ascending)))
                {
                    HandleDistinct(query.Select, node);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Duplicates(y => y)))
                {
                    HandleDuplicates(query.Select, node);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Duplicates(y => y, y => y, Order.Ascending)))
                {
                    HandleDuplicates(query.Select, node);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Duplicates(y => y, y => y, Order.Ascending, y => y, Order.Ascending)))
                {
                    HandleDuplicates(query.Select, node);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.OrderBy(y => y)))
                {
                    HandleOrderBy(query.Select, node, false);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.OrderByDescending(y => y)))
                {
                    HandleOrderBy(query.Select, node, true);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Take(0)))
                {
                    query.Select.Top = node.ConstantArgumentAt <int>(2); query.Select.TopType = Select.TopValueType.Count;
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.TakePercent(0)))
                {
                    query.Select.Top = node.ConstantArgumentAt <int>(2); query.Select.TopType = Select.TopValueType.Percent;
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Skip(0)))
                {
                    query.Select.Start = node.ConstantArgumentAt <int>(2) + 1;
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Single()))
                {
                    query.Select.Single = true;
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Single(y => true)))
                {
                    query.Select.Single = true; HandleWhere(query.Select, node);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.First()))
                {
                    query.Select.First = true;
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.First(y => true)))
                {
                    query.Select.First = true; HandleWhere(query.Select, node);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.FirstOrDefault()))
                {
                    query.Select.FirstOrDefault = true;
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.FirstOrDefault(y => true)))
                {
                    query.Select.FirstOrDefault = true; HandleWhere(query.Select, node);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Any()))
                {
                    query.Select.Any = true;
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Any(y => true)))
                {
                    query.Select.Any = true; HandleWhere(query.Select, node);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Count()))
                {
                    query.Select.Count = true;
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Count(y => true)))
                {
                    query.Select.Count = true; HandleWhere(query.Select, node);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Randomize()))
                {
                    query.Select.Randomize = true;
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Intersect(
                                                                           Queryable.Empty <T>(), new Expression <Func <T, object> >[] { })))
                {
                    HandleSetOperation(query.Select, node, true, _getTableName);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.Except(
                                                                           Queryable.Empty <T>(), new Expression <Func <T, object> >[] { })))
                {
                    HandleSetOperation(query.Select, node, false, _getTableName);
                }
                else if (node.MatchesMethodSignature <IQueryable <T> >(x => x.SyncWith(Queryable.Empty <T>(), y => y,
                                                                                       SyncFields.Exclude, new Expression <Func <T, object> >[] { })))
                {
                    HandleSync(query, node);
                }
                else
                {
                    throw new QueryOperatorNotSupportedException(node.Method);
                }
            }

            VisitMethodCall(node, query, query, true, true, node.Arguments.Skip(1).ToArray());
        }
Exemple #8
0
 public static T ArgumentAt <T>(this MethodCallExpression method, int index) where T : Expression
 {
     return((T)method.ArgumentAt(index));
 }
Exemple #9
0
 public static bool ArgumentIsOfType <T>(this MethodCallExpression method, int index)
 {
     return(TypesAreAssignable(method.ArgumentAt(index).Type, typeof(T)));
 }
 protected override void VisitMethodCall(Context context, MethodCallExpression node)
 {
     if (node.MatchesMethodSignature <string>(x => x.StartsWith(string.Empty)))
     {
         var projection = Projection.Create.Function(Function.Create.StartsWith());
         context.State(projection);
         var argumentsState = new Dictionary <Expression, Action <Projection> >
         {
             { node.ArgumentAt(1), x => projection.Function.StartsWith.Value = x }
         };
         VisitMethodCall(node, x => projection.Function.StartsWith.Text = x, argumentsState, true, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.Contains(string.Empty)))
     {
         var projection = Projection.Create.Function(Function.Create.Contains());
         context.State(projection);
         var argumentsState = new Dictionary <Expression, Action <Projection> >
         {
             { node.ArgumentAt(1), x => projection.Function.Contains.Value = x }
         };
         VisitMethodCall(node, x => projection.Function.Contains.Text = x, argumentsState, true, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.EndsWith(string.Empty)))
     {
         var projection = Projection.Create.Function(Function.Create.EndsWith());
         context.State(projection);
         var argumentsState = new Dictionary <Expression, Action <Projection> >
         {
             { node.ArgumentAt(1), x => projection.Function.EndsWith.Value = x }
         };
         VisitMethodCall(node, x => projection.Function.EndsWith.Text = x, argumentsState, true, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.ToLower()))
     {
         var projection = Projection.Create.Function(Function.Create.ToLower());
         context.State(projection);
         VisitMethodCall(node, x => projection.Function.ToLower.Text = x, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.ToUpper()))
     {
         var projection = Projection.Create.Function(Function.Create.ToUpper());
         context.State(projection);
         VisitMethodCall(node, x => projection.Function.ToUpper.Text = x, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.Trim()))
     {
         var projection = Projection.Create.Function(Function.Create.Trim());
         context.State(projection);
         VisitMethodCall(node, x => projection.Function.Trim.Text = x, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.TrimEnd()))
     {
         var projection = Projection.Create.Function(Function.Create.TrimEnd());
         context.State(projection);
         VisitMethodCall(node, x => projection.Function.TrimEnd.Text = x, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.TrimStart()))
     {
         var projection = Projection.Create.Function(Function.Create.TrimStart());
         context.State(projection);
         VisitMethodCall(node, x => projection.Function.TrimStart.Text = x, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.ToString()))
     {
         var projection = Projection.Create.Function(Function.Create.ToString());
         context.State(projection);
         VisitMethodCall(node, x => projection.Function.ToString.Value = x, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.Substring(0)))
     {
         var projection = Projection.Create.Function(Function.Create.Substring());
         context.State(projection);
         var argumentsState = new Dictionary <Expression, Action <Projection> >
         {
             { node.ArgumentAt(1), x => projection.Function.Substring.Start = x }
         };
         VisitMethodCall(node, x => projection.Function.Substring.Text = x, argumentsState, true, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.Substring(0, 0)))
     {
         var projection = Projection.Create.Function(Function.Create.SubstringFixed());
         context.State(projection);
         var argumentsState = new Dictionary <Expression, Action <Projection> >
         {
             { node.ArgumentAt(1), x => projection.Function.SubstringFixed.Start = x },
             { node.ArgumentAt(2), x => projection.Function.SubstringFixed.Length = x }
         };
         VisitMethodCall(node, x => projection.Function.SubstringFixed.Text = x, argumentsState, true, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.Replace(string.Empty, string.Empty)))
     {
         var projection = Projection.Create.Function(Function.Create.Replace());
         context.State(projection);
         var argumentsState = new Dictionary <Expression, Action <Projection> >
         {
             { node.ArgumentAt(1), x => projection.Function.Replace.SearchValue = x },
             { node.ArgumentAt(2), x => projection.Function.Replace.ReplaceValue = x }
         };
         VisitMethodCall(node, x => projection.Function.Replace.Text = x, argumentsState, true, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.Insert(0, string.Empty)))
     {
         var projection = Projection.Create.Function(Function.Create.Insert());
         context.State(projection);
         var argumentsState = new Dictionary <Expression, Action <Projection> >
         {
             { node.ArgumentAt(1), x => projection.Function.Insert.Start = x },
             { node.ArgumentAt(2), x => projection.Function.Insert.Value = x }
         };
         VisitMethodCall(node, x => projection.Function.Insert.Text = x, argumentsState, true, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.IndexOf(string.Empty)))
     {
         var projection = Projection.Create.Function(Function.Create.IndexOf());
         context.State(projection);
         var argumentsState = new Dictionary <Expression, Action <Projection> >
         {
             { node.ArgumentAt(1), x => projection.Function.IndexOf.Value = x }
         };
         VisitMethodCall(node, x => projection.Function.IndexOf.Text = x, argumentsState, true, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.IndexOf(string.Empty, 0)))
     {
         var projection = Projection.Create.Function(Function.Create.IndexOfAt());
         context.State(projection);
         var argumentsState = new Dictionary <Expression, Action <Projection> >
         {
             { node.ArgumentAt(1), x => projection.Function.IndexOfAt.Value = x },
             { node.ArgumentAt(2), x => projection.Function.IndexOfAt.Start = x }
         };
         VisitMethodCall(node, x => projection.Function.IndexOfAt.Text = x, argumentsState, true, true);
     }
     else if (node.MatchesMethodSignature <string>(x => x.Hash(EntityExtensions.HashAlgorithim.Md5)))
     {
         var projection = Projection.Create.Function(Function.Create.Hash(node.ConstantArgumentAt <EntityExtensions.HashAlgorithim>(2) == EntityExtensions.HashAlgorithim.Md5 ?
                                                                          Function.HashParameters.HashType.Md5 :
                                                                          Function.HashParameters.HashType.Sha1));
         context.State(projection);
         var argumentsState = new Dictionary <Expression, Action <Projection> >
         {
             { node.ArgumentAt(1), x => projection.Function.Hash.Value = x }
         };
         VisitMethodCall(node, argumentsState, true, node.ArgumentAt(2));
     }
     else if (node.MatchesMethodSignature <byte[]>(x => x.ToHex()))
     {
         var projection = Projection.Create.Function(Function.Create.ToHex());
         context.State(projection);
         var argumentsState = new Dictionary <Expression, Action <Projection> >
         {
             { node.ArgumentAt(1), x => projection.Function.ToHex.Value = x }
         };
         VisitMethodCall(node, argumentsState, true);
     }
     else if (node.Object != null && node.Object.NodeType == ExpressionType.MemberAccess &&
              node.Object.Type.GetInterfaces().Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IDictionary <,>)) &&
              node.MatchesMethodName("get_Item"))
     {
         context.State(Projection.Create.Field(((MemberExpression)node.Object).Member.Name, node.Arguments[0].EvaluateExpression <string>(), _tableAlias));
     }
     else
     {
         context.State(Projection.Create.Constant(node.EvaluateExpression()));
     }
 }