Пример #1
0
 public JoinedTableExpression(IAliasedExpression left, IAliasedExpression right, JoinType joinType, TableAlias alias)
     : base(alias)
 {
     LeftTable = left;
     RightTable = right;
     JoinType = joinType;
 }
Пример #2
0
 public JoinedTableExpression Replace(TableAlias aliasToFind, IAliasedExpression expressionReplacement)
 {
     JoinedTableExpression result;
     if (LeftTable.Alias == aliasToFind)
     {
         LeftTable = expressionReplacement;
         return (JoinedTableExpression)new Visitors.LazyAliasResolver(new Dictionary<TableAlias, TableAlias>() { { aliasToFind, expressionReplacement.Alias } }).Visit(this);
     }
     if (RightTable.Alias == aliasToFind)
     {
         RightTable = expressionReplacement;
         return (JoinedTableExpression)new Visitors.LazyAliasResolver(new Dictionary<TableAlias, TableAlias>() { { aliasToFind, expressionReplacement.Alias } }).Visit(this);
     }
     if (LeftTable is JoinedTableExpression && (result = ((JoinedTableExpression)LeftTable).Replace(aliasToFind, expressionReplacement)) != null)
     {
         LeftTable = result;
         //LeftTable = (JoinedTableExpression)new Visitors.LazyAliasResolver(new Dictionary<TableAlias, TableAlias>() { { aliasToFind, expressionReplacement.Alias } }).Visit(this);
         return this;
     }
     if (RightTable is JoinedTableExpression && (result = ((JoinedTableExpression)RightTable).Replace(aliasToFind, expressionReplacement)) != null)
     {
         RightTable = result;
         //RightTable = new Visitors.LazyAliasResolver(new Dictionary<TableAlias, TableAlias>() { { aliasToFind, expressionReplacement.Alias } }).Visit(this);
         return this;
     }
     return null;
 }
Пример #3
0
 public JoinedTableExpression(IAliasedExpression left, IAliasedExpression right, JoinType joinType, TableAlias alias, Evaluant.NLinq.Expressions.BinaryExpression on)
     : base(alias)
 {
     LeftTable = left;
     RightTable = right;
     JoinType = joinType;
     On = on;
 }
Пример #4
0
 public EntityReferenceExpression(TableAlias alias, IAliasedExpression target)
     : base(alias)
 {
     this.Target = target;
 }
Пример #5
0
 public EntityReferenceExpression(IAliasedExpression target)
     : base(target.Alias)
 {
     this.Target = target;
 }
Пример #6
0
 public virtual KeyValuePair<ColumnExpression, NLinq.Expressions.Expression> Update(KeyValuePair<ColumnExpression, NLinq.Expressions.Expression> item, IAliasedExpression column, Evaluant.NLinq.Expressions.Expression value)
 {
     if (item.Key != column || item.Value != value)
         return new KeyValuePair<ColumnExpression, NLinq.Expressions.Expression>((ColumnExpression)column, value);
     return item;
 }
Пример #7
0
 public virtual IAliasedExpression Update(JoinedTableExpression item, IAliasedExpression leftTable, IAliasedExpression rightTable, JoinType joinType, TableAlias alias, Evaluant.NLinq.Expressions.BinaryExpression on)
 {
     if (item.LeftTable != leftTable || item.RightTable != rightTable || item.JoinType != joinType || item.Alias != alias)
         return new JoinedTableExpression(leftTable, rightTable, joinType, alias, on);
     return item;
 }
Пример #8
0
 internal IAliasedExpression Update(Union item, TableAlias alias, IAliasedExpression[] aliasedExpression)
 {
     if (item.SelectStatements != aliasedExpression || item.Alias != alias)
         return new Union(alias, aliasedExpression);
     return item;
 }
Пример #9
0
 public virtual FromClause Update(FromClause item, IAliasedExpression[] originalFroms, IEnumerable<IAliasedExpression> froms)
 {
     if (originalFroms != froms)
         return new FromClause(froms);
     return item;
 }
Пример #10
0
        //public virtual MethodCall Update(MethodCall call, Evaluant.NLinq.Expressions.Expression target, Evaluant.NLinq.Expressions.Identifier methodName, Evaluant.NLinq.Expressions.Expression[] parameters)
        //{
        //    if (call.Target != target || call.MethodName != methodName || call.Parameters != parameters)
        //        return new MethodCall(target, methodName, parameters);
        //    return call;
        //}

        //public virtual PropertyReferenceExpression Update(PropertyReferenceExpression item, AliasedExpression target, Evaluant.NLinq.Expressions.Identifier propertyName)
        //{
        //    return Update(item, item.Alias, item.Target, item.PropertyName);
        //}

        //public virtual PropertyReferenceExpression Update(PropertyReferenceExpression item, TableAlias alias, AliasedExpression target, Evaluant.NLinq.Expressions.Identifier propertyName)
        //{
        //    if (item.Alias != alias || item.PropertyName != propertyName || item.Target != target)
        //        return new PropertyReferenceExpression(alias, target, propertyName);
        //    return item;
        //}

        //public virtual MethodCall Update(MethodCall item, Evaluant.NLinq.Expressions.Expression target, Evaluant.NLinq.Expressions.Expression[] parameters, Evaluant.NLinq.Expressions.Identifier methodName)
        //{
        //    if (item.MethodName != methodName || item.Parameters != parameters || item.Target != target)
        //        return new MethodCall(target, methodName, parameters);
        //    return item;
        //}

        public virtual EntityReferenceExpression Update(EntityReferenceExpression item, IAliasedExpression target)
        {
            if (item.Target != target)
                return new EntityReferenceExpression(target);
            return item;
        }
Пример #11
0
 public JoinedTableExpression(IAliasedExpression left, IAliasedExpression right, JoinType joinType, Evaluant.NLinq.Expressions.BinaryExpression on)
     : this(left, right, joinType, right.Alias, on)
 {
 }
Пример #12
0
 public JoinedTableExpression(IAliasedExpression left, IAliasedExpression right, JoinType joinType)
     : this(left, right, joinType, right.Alias)
 {
 }
Пример #13
0
 public JoinedTableExpression(IAliasedExpression left, IAliasedExpression right)
     : this(left, right, JoinType.Inner)
 {
 }
Пример #14
0
        public override Evaluant.NLinq.Expressions.Expression Visit(Evaluant.NLinq.Expressions.MemberExpression expression)
        {
            if (getAlias)
            {
                if (expression.Previous is EntityIdentifier)
                {
                    EntityIdentifier identifier = (EntityIdentifier)expression.Previous;
                    if (!entityIdentifierAliases.ContainsKey(identifier.Text))
                        entityIdentifierAliases.Add(identifier.Text, identifier.Entity.Alias);
                    return identifier;
                }

                if (expression.Previous != null)
                    return Visit(expression.Previous);
                return base.Visit(expression);

            }
            if (getPreviousType)
            {
                if (expression.Previous is EntityIdentifier)
                    return ((EntityIdentifier)expression.Previous).Entity;

                if (expression.Previous != null)
                {
                    EntityExpression entity = (EntityExpression)Visit(expression.Previous);
                    Model.Reference reference = engine.Factory.Model.Entities[entity.Type].References[((Evaluant.NLinq.Expressions.Identifier)expression.Statement).Text];
                    entity = new EntityExpression(new TableAlias()) { Type = reference.ChildType, Expression = expression };
                    return entity;
                }
            }

            if (expression.Statement.ExpressionType == NLinq.Expressions.ExpressionTypes.Call)
            {
                NLinq.Expressions.MethodCall item = (NLinq.Expressions.MethodCall)expression.Statement;
                AggregateFunctionType aggregateType;
                switch (item.Identifier.Text)
                {
                    case "Count":
                        aggregateType = AggregateFunctionType.Count;
                        break;
                    case "Average":
                        aggregateType = AggregateFunctionType.Avg;
                        break;
                    case "Max":
                        aggregateType = AggregateFunctionType.Max;
                        break;
                    case "Min":
                        aggregateType = AggregateFunctionType.Min;
                        break;
                    case "Sum":
                        aggregateType = AggregateFunctionType.Sum;
                        break;
                    default:
                        aggregateType = AggregateFunctionType.Unknown;
                        break;
                }
                if (aggregateType == AggregateFunctionType.Unknown)
                {
                    SelectStatement oldSelect = select;
                    if (item.Identifier.Text == "Take")
                    {
                        Visit(expression.Previous);
                        select.Top = (int)((Constant)item.Parameters[0]).Value;
                        return select;
                    }
                    if (item.Identifier.Text == "Skip")
                    {
                        Visit(expression.Previous);
                        if (Convert.ToInt32(((Constant)item.Parameters[0]).Value) == 0)
                            return select;

                        if (select.OrderBy == null)
                            throw new NotSupportedException("A skip operation cannot be done on a statement which is not ordered");


                        List<IAliasedExpression> columns = new List<IAliasedExpression>(select.Columns);
                        columns.Add(new ComplexColumnExpression(null, new RowNumber(select.OrderBy), "rn" + select.Alias));
                        select.Columns = columns.ToArray();
                        columns.RemoveAt(columns.Count - 1);
                        oldSelect = select;
                        select = new SelectStatement(new TableAlias(), null, new FromClause(select), null, new NLinq.Expressions.WhereClause(new NLinq.Expressions.BinaryExpression(NLinq.Expressions.BinaryExpressionType.Greater, new ColumnExpression(select.Alias, "rn" + select.Alias), item.Parameters[0])));
                        columns = new List<IAliasedExpression>();
                        foreach (IAliasedExpression expr in oldSelect.Columns)
                        {
                            IAliasedExpression column = null;
                            if (expr.DbExpressionType == DbExpressionType.Column)
                            {
                                column = new ColumnExpression(oldSelect.Alias, ((ColumnExpression)expr).ColumnAlias, ((ColumnExpression)expr).ColumnAlias);
                            }
                            else if (expr.DbExpressionType == DbExpressionType.Entity)
                            {
                                EntityExpression entity = expr as EntityExpression;
                                column = new ComplexColumnExpression(oldSelect.Alias, new NLinq.Expressions.MemberExpression(((NLinq.Expressions.MemberExpression)entity.Expression).Statement, entity.Expression));
                            }
                            else
                                throw new NotSupportedException();
                            if (column != null)
                                columns.Add(column);
                        }
                        if (oldSelect.OrderBy != null && oldSelect.OrderBy.Count > 0)
                        {
                            List<Evaluant.NLinq.Expressions.OrderByCriteria> criterias = new List<NLinq.Expressions.OrderByCriteria>();
                            foreach (var criteria in oldSelect.OrderBy.Criterias)
                            {
                                if (criteria.Expression != null)
                                {
                                    if (criteria.Expression.ExpressionType == NLinq.Expressions.ExpressionTypes.MemberAccess)
                                    {
                                        criterias.Add(new NLinq.Expressions.OrderByCriteria(new ColumnExpression(oldSelect.Alias, (NLinq.Expressions.Identifier)((NLinq.Expressions.MemberExpression)criteria.Expression).Statement), criteria.Ascending));
                                    }
                                }
                            }
                            if (criterias.Count > 0)
                                select.OrderBy = new NLinq.Expressions.OrderByClause(criterias);
                        }
                        //Since we include a surrounding select, we need to clone some information with alias changing
                        var aliasChanger = new LazyAliasResolver(new Dictionary<TableAlias, TableAlias> { { TableAlias.All, oldSelect.Alias } });
                        select.Columns = aliasChanger.VisitColumns(columns);

                        select.OrderBy = aliasChanger.VisitOrderBy(select.OrderBy);
                        oldSelect.OrderBy = null;
                        return select;
                    }
                    if (item.Identifier.Text == "First")
                    {
                        Visit(expression.Previous);
                        select.Top = 1;
                        return select;
                    }
                    if (item.Identifier.Text == "Last")
                    {
                        Visit(expression.Previous);
                        if (select.OrderBy != null && select.OrderBy.Criterias != null && select.OrderBy.Criterias.Count > 0)
                        {
                            foreach (NLinq.Expressions.OrderByCriteria criteria in select.OrderBy.Criterias)
                            {
                                criteria.Ascending = !criteria.Ascending;
                            }
                        }
                        else
                            throw new NotSupportedException("To use Last or LastOrDefault, you have to specify an order in your query.");
                        select.Top = 1;
                        return select;
                    }
                    if (item.Identifier.Text == "Any")
                    {
                        if (expression.Previous.ExpressionType != NLinq.Expressions.ExpressionTypes.Quote)
                        {
                            select = new SelectStatement(new TableAlias());
                            select.Columns = new[] { new ComplexColumnExpression(
                                    null,
                                    new Constant(1, System.Data.DbType.Int32)) 
                                };
                            select.Where = new NLinq.Expressions.WhereClause(Visit(expression.Previous));
                            var result = new Exists(select);
                            select = oldSelect;
                            return result;
                        }
                        return new Exists(Visit(expression.Previous));
                    }
                    if (item.Identifier.Text == "Distinct")
                    {
                        Visit(expression.Previous);
                        select.Distinct = true;
                        return select;
                    }
                    return expression;
                    select = new SelectStatement(new TableAlias());
                    Visit(expression.Previous);
                    SelectStatement previousSelect = select;
                    select = oldSelect;
                    if (item.Parameters.Length == 0)
                        return new SelectStatement(new TableAlias(), new IAliasedExpression[] { new Aggregate(item.Identifier, ColumnExpression.AllColumns) }, new FromClause(previousSelect), null, null);
                    else
                        return new SelectStatement(new TableAlias(), new IAliasedExpression[] { new Aggregate(item.Identifier, item.Parameters) }, new FromClause(previousSelect), null, null);
                }
                else
                {
                    IAliasedExpression result;
                    if (expression.Previous is Evaluant.NLinq.Expressions.MemberExpression)
                    {
                        //If we are aggregating results
                        if (select == null)
                        {
                            Visit(expression.Previous);
                            SelectStatement oldSelect = select;
                            select = new SelectStatement(new TableAlias());
                            var columns = new IAliasedExpression[] { new Aggregate(aggregateType, new Constant(1, System.Data.DbType.Int32)) };
                            select.Columns = columns;
                            select.From = new FromClause(oldSelect);
                            //Prevent order by if counting (useless, and causes crashes on SQLServer
                            if (oldSelect.OrderBy != null)
                                oldSelect.OrderBy = null;
                            return select;
                        }
                        else
                        {
                            SelectStatement oldSelect = select;
                            select = new SelectStatement(new TableAlias());
                            //from var veryPrevious in oldSelect.From 
                            //from var a in expression.Previous 
                            //where veryPrevious==oldSelect.Select
                            //select a
                            getAlias = true;
                            EntityIdentifier identifier = (EntityIdentifier)Visit(expression);
                            getAlias = false;
                            getPreviousType = true;
                            EntityExpression previousEntity = (EntityExpression)Visit(expression.Previous);
                            getPreviousType = false;
                            select.From = oldSelect.From;

                            Evaluant.NLinq.Expressions.Identifier generatedIdentifier = new Evaluant.NLinq.Expressions.Identifier("source" + expression.GetHashCode());
                            generatedIdentifier = new EntityIdentifier(generatedIdentifier, new EntityExpression(identifier.Entity.Alias) { Type = previousEntity.Type, Expression = generatedIdentifier });

                            Evaluant.NLinq.Expressions.Identifier generatedTargetIdentifier = new Evaluant.NLinq.Expressions.Identifier("target" + expression.GetHashCode());
                            generatedTargetIdentifier = new EntityIdentifier(generatedTargetIdentifier, new EntityExpression(new TableAlias()) { Type = previousEntity.Type, Expression = generatedTargetIdentifier });

                            //from generatedIdentifier
                            //from generatedTargetIdentifier in expression
                            //where generatedIdentifier==identifier
                            //select generatedTargetIdentifier


                            //Add a join to load the reference on which we want to aggregate
                            Evaluant.NLinq.Expressions.QueryExpression query = new Evaluant.NLinq.Expressions.QueryExpression(
                                new NLinq.Expressions.FromClause(identifier.Entity.Type, generatedIdentifier, null),
                                new Evaluant.NLinq.Expressions.QueryBody(
                                    new Evaluant.NLinq.Expressions.ClauseList{
                            new NLinq.Expressions.FromClause(previousEntity.Type, generatedTargetIdentifier, expression.Previous),
                                    new Evaluant.NLinq.Expressions.WhereClause(
                            new Evaluant.NLinq.Expressions.BinaryExpression(
                                Evaluant.NLinq.Expressions.BinaryExpressionType.Equal,
                                    new EntityReferenceExpression(((EntityIdentifier)generatedIdentifier).Entity),
                                    new EntityReferenceExpression(identifier.Entity)))
                                }, new Evaluant.NLinq.Expressions.SelectClause(
                                        new EntityReferenceExpression(((EntityIdentifier)generatedTargetIdentifier).Entity)),
                                    null));

                            result = (IAliasedExpression)Visit(query);
                            select = oldSelect;
                        }
                    }
                    else
                        result = (IAliasedExpression)Visit(expression.Previous);
                    if (item.Parameters.Length == 0)
                        result = new SelectStatement(new TableAlias(), new IAliasedExpression[] { new Aggregate(aggregateType, ColumnExpression.AllColumns) }, new FromClause(result), null, null);
                    else
                        result = new SelectStatement(new TableAlias(), new IAliasedExpression[] { new Aggregate(aggregateType, item.Parameters) }, new FromClause(result), null, null);
                    return (NLinq.Expressions.Expression)result;
                }
            }
            return base.Visit(expression);

            //throw new NotSupportedException("There should be at least one previous");
        }