Exemple #1
0
        public IEnumerable <IStatementBase> Build(DataSelectContext context)
        {
            var statement = new SelectStatement(context.Entity)
            {
                Paging = context.Paging
            };

            //生成分组子句
            if (context.Grouping != null)
            {
                this.GenerateGrouping(statement, context.Grouping);
            }

            //生成查询成员
            if (context.Schema != null && !context.Schema.IsEmpty)
            {
                foreach (var member in context.Schema.Members)
                {
                    //生成数据模式对应的子句
                    this.GenerateSchema(statement, statement.Table, member);
                }
            }

            //生成条件子句
            statement.Where = statement.Where(context.Validate());

            //生成排序子句
            this.GenerateSortings(statement, statement.Table, context.Sortings);

            yield return(statement);
        }
Exemple #2
0
        private void GenerateGrouping(SelectStatement statement, Grouping grouping)
        {
            if (grouping == null)
            {
                return;
            }

            if (grouping.Keys != null && grouping.Keys.Length > 0)
            {
                //创建分组子句
                statement.GroupBy = new GroupByClause();

                foreach (var key in grouping.Keys)
                {
                    var source = statement.From(key.Name, null, out var property);

                    if (property.IsComplex)
                    {
                        throw new DataException($"The grouping key '{property.Name}' can not be a complex property.");
                    }

                    statement.GroupBy.Keys.Add(source.CreateField(property));
                    statement.Select.Members.Add(source.CreateField(property.GetFieldName(out var alias), key.Alias ?? alias));
                }

                if (grouping.Filter != null)
                {
                    statement.GroupBy.Having = statement.Where(grouping.Filter);
                }
            }

            foreach (var aggregate in grouping.Aggregates)
            {
                if (string.IsNullOrEmpty(aggregate.Name) || aggregate.Name == "*")
                {
                    statement.Select.Members.Add(
                        new AggregateExpression(aggregate.Function, Expression.Constant(0))
                    {
                        Alias = string.IsNullOrEmpty(aggregate.Alias) ? aggregate.Function.ToString() : aggregate.Alias
                    });
                }
                else
                {
                    var source = statement.From(aggregate.Name, null, out var property);

                    if (property.IsComplex)
                    {
                        throw new DataException($"The field '{property.Name}' of aggregate function can not be a complex property.");
                    }

                    statement.Select.Members.Add(
                        new AggregateExpression(aggregate.Function, source.CreateField(property))
                    {
                        Alias = string.IsNullOrEmpty(aggregate.Alias) ? aggregate.Name : aggregate.Alias
                    });
                }
            }
        }
Exemple #3
0
        public IEnumerable <IStatementBase> Build(DataSelectContext context)
        {
            var statement = new SelectStatement(context.Entity)
            {
                Paging = context.Paging
            };

            if (statement.Select != null)
            {
                statement.Select.IsDistinct = context.Options.IsDistinct;
            }

            //生成分组子句
            if (context.Grouping != null)
            {
                this.GenerateGrouping(context.Aliaser, statement, context.Grouping);
            }

            //生成查询成员
            if (context.Schema != null && !context.Schema.IsEmpty)
            {
                if (context.Grouping == null)
                {
                    foreach (var member in context.Schema.Members)
                    {
                        //生成数据模式对应的子句
                        this.GenerateSchema(context.Aliaser, statement, statement.Table, member);
                    }
                }
                else
                {
                    foreach (var member in context.Schema.Members)
                    {
                        if (member.Token.Property.IsComplex)
                        {
                            this.GenerateSchema(context.Aliaser, statement, statement.Table, member);
                        }
                    }
                }
            }

            //生成条件子句
            statement.Where = statement.Where(context.Validate(), context.Aliaser);

            //生成排序子句
            this.GenerateSortings(context.Aliaser, statement, statement.Table, context.Sortings);

            yield return(statement);
        }
        private IExpression GenerateAggregate(TContext context, IStatementBase statement, Operand.AggregateOperand aggregate)
        {
            var                 entity = this.GetEntity(context);
            SelectStatement     selection;
            IDataEntityProperty property;
            FieldIdentifier     field;
            var                 parts = aggregate.Member.Split('.', StringSplitOptions.RemoveEmptyEntries);

            switch (parts.Length)
            {
            case 1:
                if (!entity.Properties.TryGet(parts[0], out property))
                {
                    throw new DataException($"The specified '{parts[0]}' field does not exist in the '{entity.Name}' entity.");
                }

                selection = new SelectStatement(entity);
                field     = selection.Table.CreateField(property);
                selection.Select.Members.Add(new AggregateExpression(aggregate.Function, aggregate.Distinct, field));

                break;

            case 2:
                if (!entity.Properties.TryGet(parts[0], out property))
                {
                    throw new DataException($"The specified '{parts[0]}' field does not exist in the '{entity.Name}' entity.");
                }

                if (property.IsSimplex)
                {
                    throw new DataException($"The specified '{parts[0]}' is a simple property and cannot be navigated.");
                }

                var complex = (IDataEntityComplexProperty)property;

                selection = new SelectStatement(complex.Foreign);
                field     = selection.Table.CreateField(complex.Foreign.Properties.Get(parts[1]));
                selection.Select.Members.Add(new AggregateExpression(aggregate.Function, aggregate.Distinct, field));

                var conditions = ConditionExpression.And();

                foreach (var link in complex.Links)
                {
                    ISource src = statement.Table;

                    foreach (var anchor in link.GetAnchors())
                    {
                        if (anchor.IsComplex)
                        {
                            src = selection.Join(context.Aliaser, selection, (IDataEntityComplexProperty)anchor);
                        }
                        else
                        {
                            conditions.Add(Expression.Equal(
                                               selection.Table.CreateField(link.ForeignKey),
                                               src.CreateField(anchor)));
                        }
                    }
                }

                selection.Where = conditions;
                break;

            default:
                throw new DataException($"Invalid aggregate member ‘{aggregate.Member}’ because its navigation level is too deep.");
            }

            if (aggregate.Filter != null)
            {
                if (selection.Where == null)
                {
                    selection.Where = selection.Where(aggregate.Filter.Flatten(), context.Aliaser);
                }
                else
                {
                    selection.Where = ConditionExpression.And(selection.Where, selection.Where(aggregate.Filter.Flatten(), context.Aliaser));
                }
            }

            selection.Table.Alias = null;
            return(selection);
        }