Пример #1
0
        public void Process(DeleteEntityCommand c)
        {
            EntityMapping deleteEntityMapping = _Mapping.Entities[c.Type, true];
            Hashtable cmds = new Hashtable();

            foreach (ReferenceMapping refm in deleteEntityMapping.References)
            {
                Evaluant.Uss.Models.Reference reference = _Engine.Model.GetReference(c.Type, refm.Name);
                EntityMapping entityChildMapping = _Mapping.Entities[refm.EntityChild];

                if (!reference.ToMany)
                    continue;
                foreach (RuleMapping rulem in refm.Rules)
                {
                    if (rulem.ParentTable == deleteEntityMapping.Table)
                    {
                        // update child table
                        SQLCommand cmd = (SQLCommand)cmds[rulem.ChildTable];
                        EntityMapping childEntity = _Mapping.Entities[refm.EntityChild];
                        if (!reference.IsComposition && rulem.ChildTable == childEntity.Table)
                        {
                            if (cmd == null)
                            {
                                cmd = new UpdateCommand(rulem, rulem.ChildTable);
                                cmds.Add(rulem.ChildTable, cmd);
                            }
                        }
                        else
                        {
                            if (cmd == null)
                            {
                                cmd = new DeleteCommand(rulem, rulem.ChildTable);
                                cmds.Add(rulem.ChildTable, cmd);
                            }
                        }

                        //if (cmd is DeleteCommand)
                        //    continue;

                        for (int i = 0; i < rulem.ParentFields.Length; i++)
                        {
                            DbType dbType;
                            if (deleteEntityMapping.IdFields.Contains(refm.Rules[0].ParentFields[i]))
                            {
                                dbType = _Dialect.GetDbTypeToPrimaryKey(deleteEntityMapping.Ids[refm.Rules[0].ParentFields[i]].Generator);
                            }
                            else
                            {
                                dbType = _Dialect.GetDbTypeToPrimaryKey(childEntity.Ids[refm.Rules[0].ChildFields[i]].Generator);
                            }


                            Constant newValue;
                            if (rulem.ParentDefaultValues.Length > i && !string.IsNullOrEmpty(rulem.ParentDefaultValues[i]))
                                newValue = new Constant(rulem.ParentDefaultValues[i], dbType);
                            else
                                newValue = new Constant(DBNull.Value, dbType);

                            // SSX 28/01/08: add contains test
                            if (entityChildMapping.Ids[rulem.ChildFields[i]] == null && cmd is UpdateCommand
                                && !((UpdateCommand)cmd).ColumnValueCollection.Contains(rulem.ChildFields[i]))
                                ((UpdateCommand)cmd).ColumnValueCollection.Add(rulem.ChildFields[i], newValue);

                            Column childField = new Column(rulem, rulem.ChildFields[i]);
                            Constant childParameter = new Constant(ConvertId(deleteEntityMapping, rulem.ParentFields[i], c.ParentId), dbType);
                            BinaryLogicExpression parentClause = new BinaryLogicExpression(childField, BinaryLogicOperator.Equals, childParameter);
                            if (cmd is UpdateCommand)
                                ((UpdateCommand)cmd).WhereClause.SearchCondition.Add(parentClause);
                            else
                                ((DeleteCommand)cmd).Condition.SearchCondition.Add(parentClause);
                        }

                        if (!string.IsNullOrEmpty(rulem.Constraint))
                            DisableForeignKeys(rulem.ChildTable);
                    }
                }
            }

            // Deletes all references to and from it first
            foreach (EntityMapping em in _Mapping.Entities)
            {
                foreach (ReferenceMapping refm in em.References)
                {
                    //Evaluant.Uss.Models.Model childModel = _Engine.Model.GetEntity(

                    if (refm.EntityChild == deleteEntityMapping.Type) // To
                    {
                        for (int indexRule = 0; indexRule < refm.Rules.Count; indexRule++)
                        {
                            RuleMapping rulem = refm.Rules[indexRule];
                            if ((rulem.ChildField == deleteEntityMapping.IdFields &&
                                deleteEntityMapping.DiscriminatorField == null) ||
                                (rulem.ChildField + ";" + deleteEntityMapping.DiscriminatorField == deleteEntityMapping.IdFields &&
                                deleteEntityMapping.DiscriminatorField != null))
                            {
                                // delete childtable

                                if (cmds.ContainsKey(rulem.ChildTable))
                                    continue;

                                DeleteCommand cmd = new DeleteCommand(rulem, rulem.ChildTable);
                                cmds.Add(rulem.ChildTable, cmd);

                                for (int index = 0; index < rulem.ChildFields.Length; index++)
                                {
                                    DbType dbType = _Dialect.GetDbTypeToPrimaryKey(deleteEntityMapping.Ids[index].Generator);

                                    cmd.Condition.SearchCondition.Add(new BinaryLogicExpression(
                                        new Column(rulem, rulem.ChildFields[index]),
                                        BinaryLogicOperator.Equals,
                                        new Constant(ConvertId(deleteEntityMapping, rulem.ChildFields[index], c.ParentId), dbType)
                                    ));
                                }


                                if (!string.IsNullOrEmpty(refm.DiscriminatorField) && indexRule == refm.Rules.Count - 1)
                                {
                                    cmd.Condition.SearchCondition.Add(new BinaryLogicExpression(
                                        new Column(rulem, refm.DiscriminatorField),
                                        BinaryLogicOperator.Equals,
                                        new Parameter(rulem, refm.DiscriminatorValue)
                                        ));
                                }

                                if (!string.IsNullOrEmpty(rulem.Constraint))
                                    DisableForeignKeys(rulem.ChildTable);
                            }

                            if (rulem.ParentField != em.IdFields && em.DiscriminatorField != null
                                || rulem.ParentTable != em.Table)
                            {
                                // update parent table
                                SQLCommand cmd = (SQLCommand)cmds[rulem.ParentTable];
                                if (cmd == null)
                                {
                                    cmd = new UpdateCommand(rulem, rulem.ParentTable);
                                    cmds.Add(rulem.ParentTable, cmd);
                                }

                                if (cmd is DeleteCommand)
                                    continue;

                                for (int i = 0; i < rulem.ParentFields.Length; i++)
                                {
                                    DbType dbType = _Dialect.GetDbTypeToPrimaryKey(deleteEntityMapping.Ids[i].Generator);

                                    Constant newValue = new Constant(DBNull.Value, dbType);
                                    if (rulem.ParentDefaultValues.Length > i && !string.IsNullOrEmpty(rulem.ParentDefaultValues[i]))
                                        newValue = new Constant(rulem.ParentDefaultValues[i], dbType);

                                    // SSX 28/01/08: add contains test
                                    if (em.Ids[rulem.ParentFields[i]] == null
                                        && !((UpdateCommand)cmd).ColumnValueCollection.Contains(rulem.ParentFields[i]))
                                        ((UpdateCommand)cmd).ColumnValueCollection.Add(rulem.ParentFields[i], newValue);

                                    Column parentField = new Column(rulem, rulem.ParentFields[i]);
                                    Constant parentParameter = new Constant(ConvertId(deleteEntityMapping, rulem.ParentFields[i], c.ParentId), dbType);
                                    BinaryLogicExpression parentClause = new BinaryLogicExpression(parentField, BinaryLogicOperator.Equals, parentParameter);
                                    ((UpdateCommand)cmd).WhereClause.SearchCondition.Add(parentClause);
                                }

                                // UPDATE parentTable SET parentField = NULL WHERE (parentField = @parentValue AND discriminator = 'name's relation')
                                if (!string.IsNullOrEmpty(refm.DiscriminatorField) && indexRule == refm.Rules.Count - 1)
                                {
                                    Column discriminatorField = new Column(rulem, rulem.ParentField);
                                    Constant discriminatorValue = new Constant(refm.DiscriminatorValue, DbType.AnsiString);
                                    BinaryLogicExpression discriminatorClause = new BinaryLogicExpression(discriminatorField, BinaryLogicOperator.Equals, discriminatorValue);
                                    ((UpdateCommand)cmd).WhereClause.SearchCondition.Add(discriminatorClause);
                                }

                                if (!string.IsNullOrEmpty(rulem.Constraint))
                                    DisableForeignKeys(rulem.ParentTable);

                            }
                        }

                    }

                }
            }


            // Deletes all attributes if they are in a separate table
            if (deleteEntityMapping.Attributes != null)
            {
                foreach (AttributeMapping am in deleteEntityMapping.Attributes)
                {
                    if (am.Table != deleteEntityMapping.Table)
                    {
                        DeleteCommand cmd = new DeleteCommand(am, am.Table);
                        for (int index = 0; index < deleteEntityMapping.Ids.Count; index++)
                        {
                            PrimaryKeyMapping pkm = deleteEntityMapping.Ids[index];
                            cmd.Condition.SearchCondition.Add(new BinaryLogicExpression(
                                new Column(am, am.ParentFields[index]),
                                BinaryLogicOperator.Equals,
                                new Constant(ConvertId(deleteEntityMapping, pkm.Field, c.ParentId), _Dialect.GetDbTypeToPrimaryKey(pkm.Generator))));
                        }
                        cmds.Add(am.Table, cmd);
                    }
                }
            }

            // SSX 28/01/08: remove table if already existing
            if (cmds.Contains(deleteEntityMapping.Table))
            {
                cmds.Remove(deleteEntityMapping.Table);
            }

            if (!cmds.ContainsKey(deleteEntityMapping.Table))
            {
                DeleteCommand cmd = new DeleteCommand(deleteEntityMapping, deleteEntityMapping.Table);
                for (int index = 0; index < deleteEntityMapping.Ids.Count; index++)
                {
                    PrimaryKeyMapping pkm = deleteEntityMapping.Ids[index];
                    cmd.Condition.SearchCondition.Add(new BinaryLogicExpression(
                        new Column(deleteEntityMapping, pkm.Field),
                        BinaryLogicOperator.Equals,
                        new Constant(ConvertId(deleteEntityMapping, pkm.Field, c.ParentId), _Dialect.GetDbTypeToPrimaryKey(pkm.Generator))));
                }
                cmds.Add(deleteEntityMapping.Table, cmd);
            }

            foreach (string tableName in cmds.Keys)
            {

                foreach (string query in _Dialect.RenderQueries((ISQLExpression)cmds[tableName]))
                {
                    if (!string.IsNullOrEmpty(query))
                    {
                        IDbCommand cmd = _Driver.CreateCommand(query, _Connection, _Transaction);
                        if (_Engine.TraceSqlSwitch.Enabled)
                            TraceHelpler.Trace(cmd, _Dialect);

                        cmd.ExecuteNonQuery();
                    }
                }


            }


        }
Пример #2
0
        /// <summary>
        /// Processes the attributes.
        /// </summary>
        /// <param name="entityMap">Entity mapping whitch contains the attribute</param>
        /// <param name="name">Name of the attribute</param>
        /// <param name="loadAttributes"></param>
        /// <param name="checkAlias">Indicate if returned column must have an computed alias name or not</param>
        /// <returns>Return a <see cref="Column"/></returns>
        public ISQLExpression ProcessAttributes(EntityMapping entityMap, string name, bool loadAttributes, bool checkAlias)
        {
            if (name == "Id")
            {
                Table currentTable = (Table)tableContext.Peek();
                return new Column(entityMap.Ids[0], currentTable.TableAlias, entityMap.GetIdField(entityMap.Ids[0]));
            }
            else
            {
                // Exception management : attribute mapping
                AttributeMapping attributeMapping = entityMap.Attributes[name];

                //Attempt to get the attribute in the children types
                if (attributeMapping == null)
                    foreach (Evaluant.Uss.Models.Entity e in _Model.GetTree(entityMap.Type))
                    {
                        EntityMapping em = _Mapping.Entities[e.Type];
                        if ((attributeMapping = em.Attributes[name]) != null)
                            break;
                    }

                //Attempt to get the attribute in the parent types
                if (attributeMapping == null)
                {
                    Evaluant.Uss.Models.Entity cur = _Model.GetEntity(entityMap.Type);

                    while (_Model.GetParent(cur) != null)
                    {
                        cur = _Model.GetParent(cur);
                        EntityMapping current = _Mapping.Entities[cur.Type];

                        if (current.Attributes[name] != null)
                            attributeMapping = current.Attributes[name];
                    }
                }

                if (attributeMapping == null)
                    throw new UniversalStorageException(String.Format("The attribute '{0}' of the entity '{1}' is not defined in your mapping file", name, entityMap.Type));

                // If the attribute is contained in entity's table : the current query doesn't change
                if (attributeMapping.Table == entityMap.Table)
                {
                    Table currentTable = (Table)tableContext.Peek();

                    Column c = new Column(attributeMapping, currentTable.TableAlias, attributeMapping.Field);
                    //if (entityMap.Ids[attributeMapping.Field] != null)
                    //    c.ColumnName = entityMap.GetIdField(entityMap.Ids[attributeMapping.Field]);

                    if (checkAlias)
                    {
                        string attributeFullName = _Model.GetFullAttributeName(attributeMapping.Name, attributeMapping.ParentEntity.Type);
                        //if (entityMap.Ids[attributeMapping.Field] != null)
                        //    attributeFullName = entityMap.GetIdFieldAs(entityMap.Ids[attributeMapping.Field]);
                        //c.ColumnName = (_AliasColumnMapping.Contains(attributeFullName)) ? _AliasColumnMapping[attributeFullName].ToString() : "";
                        if (_AliasColumnMapping.Contains(attributeFullName))
                            c.ColumnName = _AliasColumnMapping[attributeFullName].ToString();
                    }
                    return c;
                }
                // Else : create a new select query
                else
                {
                    // Get the current context
                    Table currentTable = (Table)tableContext.Pop();
                    SelectStatement mainQuery = (SelectStatement)queryContext.Pop();

                    // Create a new query
                    SelectStatement currentQuery = new SelectStatement(attributeMapping);

                    Table attributeTable = new TableSource(attributeMapping, attributeMapping.Table, CreateUniqueAttributeAlias());
                    string atrbId = attributeMapping.Table == null || attributeMapping.Table == entityMap.Table ? entityMap.GetIdField(entityMap.Ids[0]) : attributeMapping.ParentField;

                    if (loadAttributes)
                    {
                        return this.ProcessAttributesWithLoadAttribute(mainQuery, currentQuery, currentTable, entityMap, attributeTable, attributeMapping, atrbId);
                    }
                    else
                    {
                        if (_IsFirstAttribute)
                        {
                            _IsFirstAttribute = false;

                            // if current table is a JoinedTable : 
                            //		from clause = mainQuery INNER JOIN attributeTable
                            if (currentTable.GetType() == typeof(JoinedTable))
                            {
                                JoinedTable lastJoinTable = new JoinedTable(mainQuery, loadAttributes ? TypeJoinedTable.LeftOuter : TypeJoinedTable.Inner, attributeTable);
                                lastJoinTable.TableAlias = mainQuery.TableAlias;

                                BinaryLogicExpression onCondition = new BinaryLogicExpression(
                                    new Column(entityMap.Ids[0], mainQuery.TableAlias, entityMap.GetIdField(entityMap.Ids[0])),
                                    BinaryLogicOperator.Equals,
                                    new Column(attributeMapping, attributeTable.TableAlias, atrbId));

                                if (mainQuery.WhereClause.SearchCondition.Count != 0)
                                {
                                    foreach (ILogicExpression expression in mainQuery.WhereClause.SearchCondition)
                                    {
                                        onCondition = new BinaryLogicExpression(onCondition, BinaryLogicOperator.And, expression);
                                    }
                                }

                                lastJoinTable.SearchConditions.Add(new BinaryLogicExpression(
                                    new Column(entityMap.Ids[0], mainQuery.TableAlias, entityMap.GetIdField(entityMap.Ids[0])),
                                    BinaryLogicOperator.Equals,
                                    new Column(entityMap.Ids[0], attributeTable.TableAlias, atrbId)));

                                currentQuery.TableAlias = mainQuery.TableAlias;
                                currentQuery.FromClause.Add(lastJoinTable);

                                currentQuery.WhereClause.SearchCondition.Add(new BinaryLogicExpression(
                                    new Column(attributeMapping, attributeTable.TableAlias, attributeMapping.Discriminator),
                                    BinaryLogicOperator.Equals,
                                    new Constant(name, DbType.AnsiString)));


                                tableContext.Push(lastJoinTable);
                                queryContext.Push(currentQuery);

                                return new Column(attributeMapping, attributeTable.TableAlias, attributeMapping.Field);

                            }
                            // else 
                            //		from clause = currentTable INNER JOIN attributeTable
                            else
                            {

                                JoinedTable joinTable = new JoinedTable(currentTable, loadAttributes ? TypeJoinedTable.LeftOuter : TypeJoinedTable.Inner, attributeTable);
                                joinTable.SearchConditions.Add(new BinaryLogicExpression(
                                    new Column(entityMap.Ids[0], currentTable.TableAlias, entityMap.GetIdField(entityMap.Ids[0])),
                                    BinaryLogicOperator.Equals,
                                    new Column(attributeMapping, attributeTable.TableAlias, atrbId)));


                                currentQuery.TableAlias = CreateUniqueTableAlias();
                                currentQuery.FromClause.Add(joinTable);
                                currentQuery.WhereClause.SearchCondition = mainQuery.WhereClause.SearchCondition;

                                tableContext.Push(joinTable);
                            }
                        }
                        else
                        {
                            Table rightTable = ((JoinedTable)currentTable).RigthTable;

                            JoinedTable joinTable = new JoinedTable(attributeTable, TypeJoinedTable.Inner, rightTable);
                            joinTable.SearchConditions.Add(new BinaryLogicExpression(
                                new Column(attributeMapping, rightTable.TableAlias, atrbId),
                                BinaryLogicOperator.Equals,
                                new Column(attributeMapping, attributeTable.TableAlias, atrbId)));

                            ((JoinedTable)currentTable).RigthTable = joinTable;

                            currentQuery.SelectList.Add(new Column(entityMap.Ids[0], currentTable.TableAlias, entityMap.GetIdField(entityMap.Ids[0])));

                            currentQuery.TableAlias = currentTable.TableAlias;
                            currentQuery.FromClause.Add(currentTable);

                            tableContext.Push(currentTable);
                        }

                        queryContext.Push(currentQuery);
                        return new Column(attributeMapping, attributeTable.TableAlias, attributeMapping.Field);

                    }
                }
            }
        }
Пример #3
0
        private ISQLExpression ProcessAttributesWithLoadAttribute(SelectStatement mainQuery, SelectStatement currentQuery, Table currentTable, EntityMapping entityMap, Table attributeTable, AttributeMapping attributeMapping, string atrbId)
        {
            if (_IsFirstAttribute)
            {
                _IsFirstAttribute = false;

                // if current table is a JoinedTable : 
                //		from clause = mainQuery INNER JOIN attributeTable
                if (currentTable is JoinedTable)
                {
                    JoinedTable lastJoinTable = new JoinedTable(mainQuery, TypeJoinedTable.LeftOuter, attributeTable);
                    lastJoinTable.TableAlias = mainQuery.TableAlias;

                    BinaryLogicExpression onCondition = new BinaryLogicExpression(
                        new Column(entityMap.Ids[0], mainQuery.TableAlias, entityMap.GetIdField(entityMap.Ids[0])),
                        BinaryLogicOperator.Equals,
                        new Column(attributeMapping, attributeTable.TableAlias, atrbId));

                    if (mainQuery.WhereClause.SearchCondition.Count != 0)
                    {
                        foreach (ILogicExpression expression in mainQuery.WhereClause.SearchCondition)
                        {
                            onCondition = new BinaryLogicExpression(onCondition, BinaryLogicOperator.And, expression);
                        }
                    }

                    lastJoinTable.SearchConditions.Add(new BinaryLogicExpression(
                        new Column(entityMap.Ids[0], mainQuery.TableAlias, entityMap.GetIdField(entityMap.Ids[0])),
                        BinaryLogicOperator.Equals,
                        new Column(entityMap.Ids[0], attributeTable.TableAlias, atrbId)));

                    currentQuery.TableAlias = mainQuery.TableAlias;
                    currentQuery.FromClause.Add(lastJoinTable);

                    tableContext.Push(lastJoinTable);

                    for (int i = 0; i < 2; i++)
                    {
                        Column column = mainQuery.SelectList[i] as Column;
                        if (column != null && column.ColumnName == entityMap.Ids[0].Field && entityMap.Ids[0].Generator.Name == GeneratorMapping.GeneratorType.inherited)
                        {
                            column.Alias = null;
                            currentQuery.SelectList.Add(new Column(column.TagMapping, lastJoinTable.TableAlias, column.ColumnName, entityMap.GetIdFieldAs(entityMap.Ids[0])));
                        }
                        else
                        {
                            currentQuery.SelectList.Add(mainQuery.SelectList[i]);
                        }
                    }

                    if (entityMap.Ids[0].Generator.Name == GeneratorMapping.GeneratorType.inherited)
                    {
                        for (int i = 2; i < mainQuery.SelectList.Count; i++)
                        {
                            Column column = mainQuery.SelectList[i] as Column;
                            if (column != null)
                            {
                                currentQuery.SelectList.Add(new Column(column.TagMapping, lastJoinTable.TableAlias, column.GetSelectName()));
                            }
                        }
                    }

                    if (attributeMapping.Discriminator != null)
                    {
                        currentQuery.SelectList.Add(new Column(attributeMapping, attributeTable.TableAlias, attributeMapping.Discriminator));
                    }

                    queryContext.Push(currentQuery);

                    string alias = (attributeMapping.Field != attributeMapping.Name) ? attributeMapping.Name : String.Empty;
                    return new Column(attributeMapping, attributeTable.TableAlias, attributeMapping.Field);

                }
                // else 
                //		from clause = currentTable INNER JOIN attributeTable
                else
                {
                    JoinedTable joinTable = new JoinedTable(currentTable, TypeJoinedTable.LeftOuter, attributeTable);
                    joinTable.SearchConditions.Add(new BinaryLogicExpression(
                        new Column(entityMap.Ids[0], currentTable.TableAlias, entityMap.GetIdField(entityMap.Ids[0])),
                        BinaryLogicOperator.Equals,
                        new Column(attributeMapping, attributeTable.TableAlias, atrbId)));

                    currentQuery.TableAlias = currentTable.TableAlias;
                    currentQuery.FromClause.Add(joinTable);
                    currentQuery.WhereClause.SearchCondition = mainQuery.WhereClause.SearchCondition;

                    foreach (ISQLExpression exp in mainQuery.SelectList)
                    {
                        if (!currentQuery.SelectList.Contains(exp))
                            currentQuery.SelectList.Add(exp);
                    }

                    tableContext.Push(joinTable);
                }
            }
            else
            {
                Table rightTable = ((JoinedTable)currentTable).RigthTable;

                JoinedTable joinTable = new JoinedTable(rightTable, TypeJoinedTable.LeftOuter, attributeTable);
                joinTable.SearchConditions.Add(new BinaryLogicExpression(
                    new Column(attributeMapping, rightTable.TableAlias, atrbId),
                    BinaryLogicOperator.Equals,
                    new Column(attributeMapping, attributeTable.TableAlias, atrbId)));

                ((JoinedTable)currentTable).RigthTable = joinTable;

                currentQuery.TableAlias = currentTable.TableAlias;
                currentQuery.FromClause.Add(currentTable);
                currentQuery.WhereClause.SearchCondition = mainQuery.WhereClause.SearchCondition;

                tableContext.Push(currentTable);
            }



            foreach (ISQLExpression exp in mainQuery.SelectList)
            {
                if (!currentQuery.SelectList.Contains(exp))
                {
                    currentQuery.SelectList.Add(exp);
                }
            }


            if (attributeMapping.Discriminator != null)
            {
                currentQuery.SelectList.Add(new Column(attributeMapping, attributeTable.TableAlias, attributeMapping.Discriminator));
            }
            queryContext.Push(currentQuery);

            string alias1 = (attributeMapping.Field != attributeMapping.Name) ? attributeMapping.Name : String.Empty;
            return new Column(attributeMapping, attributeTable.TableAlias, attributeMapping.Field, alias1);

        }
Пример #4
0
        public override void Visit(BinaryOperator binaryop)
        {
            bool firstIsType = ((int)_ExprLevel.Peek() == EXPR);
            _ExprLevel.Push(_ExprLevel.Peek());

            ISQLExpression expression = null;

            EntityMapping entityMap = null;
            if (!firstIsType)
                entityMap = (EntityMapping)entityMappingContext.Peek();

            //	Try to get the queried attribute. If it is a date type and the 
            //	corresponding mapping is generic, we have to convert the value as ticks
            //	instead of the standard representation

            Value val = binaryop.LeftOperand as Value;
            Path path = binaryop.LeftOperand as Path;

            if (val == null)
                val = binaryop.RightOperand as Value;

            if (path == null)
                path = binaryop.RightOperand as Path;

            if (!firstIsType)
            {
                if (val != null && path != null && path.Identifiers.Count == 1)
                {
                    AttributeMapping am = entityMap.Attributes[path.Identifiers[path.Identifiers.Count - 1].Value, true];

                    if (val.Type == ValueEnum.Date)
                    {
                        //	If the field type isn't date type, convert the value as ticks
                        if (am.DbType != DbType.Date && am.DbType != DbType.DateTime && am.DbType != DbType.Time)
                        {
                            DateTime dt = Convert.ToDateTime(val.Text);
                            val.Text = Common.Utils.ConvertToString(dt, dt.GetType());
                        }
                    }
                }
            }

            ISQLExpression discriminatorConstraint = null;
            Path p = binaryop.LeftOperand as Path;
            if (p == null)
                p = binaryop.RightOperand as Path;

            if (p != null && !firstIsType)
            {
                AttributeMapping am = entityMap.Attributes[p.Identifiers[p.Identifiers.Count - 1].Value];

                if (am != null &&
                    am.Discriminator != null &&
                    am.Discriminator != string.Empty &&
                    am.DiscriminatorValue != null &&
                    am.DiscriminatorValue != string.Empty)
                {
                    Column left = new Column(am, am.Discriminator);
                    Constant right = new Constant(path.Identifiers[path.Identifiers.Count - 1].Value, DbType.AnsiStringFixedLength);
                    discriminatorConstraint = new BinaryLogicExpression(
                        left,
                        BinaryLogicOperator.Equals,
                        right);
                }
            }

            switch (binaryop.Type)
            {
                case BinaryOperatorEnum.And:
                    binaryop.LeftOperand.Accept(this);
                    ISQLExpression leftValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    binaryop.RightOperand.Accept(this);
                    ISQLExpression rightValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    expression = new BinaryLogicExpression(leftValueExpression, BinaryLogicOperator.And, rightValueExpression);

                    if (discriminatorConstraint != null)
                        expression = new BinaryLogicExpression(
                            expression,
                            BinaryLogicOperator.And,
                            discriminatorConstraint);

                    sqlExpressionContext.Push(expression);

                    break;
                case BinaryOperatorEnum.Or:
                    binaryop.LeftOperand.Accept(this);
                    leftValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    binaryop.RightOperand.Accept(this);
                    rightValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    expression = new BinaryLogicExpression(leftValueExpression, BinaryLogicOperator.Or, rightValueExpression);

                    if (discriminatorConstraint != null)
                        expression = new BinaryLogicExpression(
                            expression,
                            BinaryLogicOperator.And,
                            discriminatorConstraint);

                    sqlExpressionContext.Push(expression);

                    break;
                case BinaryOperatorEnum.Equal:

                    binaryop.LeftOperand.Accept(this);
                    leftValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    binaryop.RightOperand.Accept(this);
                    rightValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    expression = new BinaryLogicExpression(leftValueExpression, BinaryLogicOperator.Equals, rightValueExpression);

                    if (discriminatorConstraint != null)
                        expression = new BinaryLogicExpression(
                            expression,
                            BinaryLogicOperator.And,
                            discriminatorConstraint);

                    sqlExpressionContext.Push(expression);

                    break;
                case BinaryOperatorEnum.Greater:
                    binaryop.LeftOperand.Accept(this);
                    leftValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    binaryop.RightOperand.Accept(this);
                    rightValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    expression = new BinaryLogicExpression(leftValueExpression, BinaryLogicOperator.Greater, rightValueExpression);

                    if (discriminatorConstraint != null)
                        expression = new BinaryLogicExpression(
                            expression,
                            BinaryLogicOperator.And,
                            discriminatorConstraint);

                    sqlExpressionContext.Push(expression);
                    break;

                case BinaryOperatorEnum.GreaterOrEqual:
                    binaryop.LeftOperand.Accept(this);
                    leftValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    binaryop.RightOperand.Accept(this);
                    rightValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    expression = new BinaryLogicExpression(leftValueExpression, BinaryLogicOperator.GreaterOrEquals, rightValueExpression);

                    if (discriminatorConstraint != null)
                        expression = new BinaryLogicExpression(
                            expression,
                            BinaryLogicOperator.And,
                            discriminatorConstraint);

                    sqlExpressionContext.Push(expression);
                    break;
                case BinaryOperatorEnum.Lesser:
                    binaryop.LeftOperand.Accept(this);
                    leftValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    binaryop.RightOperand.Accept(this);
                    rightValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    expression = new BinaryLogicExpression(leftValueExpression, BinaryLogicOperator.Lesser, rightValueExpression);

                    if (discriminatorConstraint != null)
                        expression = new BinaryLogicExpression(
                            expression,
                            BinaryLogicOperator.And,
                            discriminatorConstraint);

                    sqlExpressionContext.Push(expression);
                    break;
                case BinaryOperatorEnum.LesserOrEqual:
                    binaryop.LeftOperand.Accept(this);
                    leftValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    binaryop.RightOperand.Accept(this);
                    rightValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    expression = new BinaryLogicExpression(leftValueExpression, BinaryLogicOperator.LesserOrEquals, rightValueExpression);

                    if (discriminatorConstraint != null)
                        expression = new BinaryLogicExpression(
                            expression,
                            BinaryLogicOperator.And,
                            discriminatorConstraint);

                    sqlExpressionContext.Push(expression);
                    break;

                case BinaryOperatorEnum.NotEqual:
                    binaryop.LeftOperand.Accept(this);
                    leftValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    binaryop.RightOperand.Accept(this);
                    rightValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    expression = new BinaryLogicExpression(leftValueExpression, BinaryLogicOperator.NotEquals, rightValueExpression);

                    if (discriminatorConstraint != null)
                        expression = new BinaryLogicExpression(
                            expression,
                            BinaryLogicOperator.And,
                            discriminatorConstraint);

                    sqlExpressionContext.Push(expression);
                    break;

                case BinaryOperatorEnum.Plus:
                case BinaryOperatorEnum.Times:
                case BinaryOperatorEnum.Div:
                case BinaryOperatorEnum.Minus:
                case BinaryOperatorEnum.Modulo:
                    binaryop.LeftOperand.Accept(this);
                    leftValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    binaryop.RightOperand.Accept(this);
                    rightValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    expression = new BinaryLogicExpression(leftValueExpression, BinaryOperatorToBinaryLogicOperator(binaryop.Type), rightValueExpression);

                    if (discriminatorConstraint != null)
                        expression = new BinaryLogicExpression(expression, BinaryLogicOperator.And, discriminatorConstraint);

                    sqlExpressionContext.Push(expression);
                    break;

                case BinaryOperatorEnum.Contains:
                    binaryop.LeftOperand.Accept(this);
                    leftValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    binaryop.RightOperand.Accept(this);
                    rightValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    expression = new LikePredicate(leftValueExpression, String.Format("%{0}%", (string)((Constant)rightValueExpression).Value));

                    if (discriminatorConstraint != null)
                        expression = new BinaryLogicExpression(
                            expression,
                            BinaryLogicOperator.And,
                            discriminatorConstraint);

                    sqlExpressionContext.Push(expression);
                    break;

                case BinaryOperatorEnum.BeginsWith:
                    binaryop.LeftOperand.Accept(this);
                    leftValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    binaryop.RightOperand.Accept(this);
                    rightValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    expression = new LikePredicate(leftValueExpression, String.Format("{0}%", (string)((Constant)rightValueExpression).Value));

                    if (discriminatorConstraint != null)
                        expression = new BinaryLogicExpression(
                            expression,
                            BinaryLogicOperator.And,
                            discriminatorConstraint);

                    sqlExpressionContext.Push(expression);

                    break;
                case BinaryOperatorEnum.EndsWith:
                    binaryop.LeftOperand.Accept(this);
                    leftValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    binaryop.RightOperand.Accept(this);
                    rightValueExpression = (ISQLExpression)sqlExpressionContext.Pop();

                    expression = new LikePredicate(leftValueExpression, String.Format("%{0}", (string)((Constant)rightValueExpression).Value));

                    if (discriminatorConstraint != null)
                        expression = new BinaryLogicExpression(
                            expression,
                            BinaryLogicOperator.And,
                            discriminatorConstraint);

                    sqlExpressionContext.Push(expression);

                    break;
            }

            _ExprLevel.Pop();
        }
Пример #5
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="firstIsType"></param>
        /// <param name="isInConstraint"></param>
        /// <param name="lastIsAttribute"></param>
        /// <param name="overrideId">True, if the Path is into a constraint and queried an attribute through Reference 
        /// (Person[Brother.MyKind.Name = 'nice'])</param>
        public void ConvertToSQL(Path path, bool firstIsType, bool isInConstraint, bool lastIsAttribute, bool overrideId)
        {
            int index = 0;

            // Process the first entity
            if (firstIsType)
            {
                Identifier ident = path.Identifiers[index++];

                //	Exception management : entity mapping
                EntityMapping entityMapping = _Mapping.Entities[ident.Value, true];

                // Save entity mapping current context
                entityMappingContext.Push(entityMapping);

                entityModelContext.Push(_Model.GetEntity(ident.Value, true));

                ProcessEntity(ident, false);
            }

            // Restore the first entity context
            EntityMapping firstMapping = (EntityMapping)entityMappingContext.Peek();
            Table firstTable = (Table)tableContext.Peek();

            // Process references
            int lastIndex = lastIsAttribute ? path.Identifiers.Count - 1 : path.Identifiers.Count;
            bool isFirstReference = true;
            ArrayList collEpression = new ArrayList();

            int stackCount = entityMappingContext.Count;

            Evaluant.Uss.Models.Entity previousEntityModel = (Evaluant.Uss.Models.Entity)entityModelContext.Peek();

            for (; index < lastIndex; index++)
            {
                Identifier ident = path.Identifiers[index];

                UnionStatement childrenSubExp = new UnionStatement();
                //childrenSubExp.TableAlias = ident.Value;

                Evaluant.Uss.Models.Reference reference =
                    _Model.GetReference(previousEntityModel.Type, ident.Value, true);

                //	ident.Value isn't a reference but an attribute
                if (_Model.GetReference(previousEntityModel.Type, ident.Value) == null &&
                    _Model.GetAttribute(previousEntityModel.Type, ident.Value) != null)
                {
                    EntityMapping tmpMap = _Mapping.Entities[previousEntityModel.Type];
                    entityMappingContext.Push(tmpMap);

                    entityModelContext.Push(_Model.GetEntity(previousEntityModel.Type));

                    continue;
                }

                Evaluant.Uss.Models.Entity currentModel = previousEntityModel;	//Model.GetEntity(previousEntityModel.Type);
                while (_Model.GetParent(currentModel) != null && reference == null)
                {
                    currentModel = Model.GetParent(currentModel);

                    //	ident.Value isn't a reference but an attribute
                    if (_Model.GetReference(currentModel.Type, ident.Value) == null &&
                        _Model.GetAttribute(currentModel.Type, ident.Value) != null)
                        continue;

                    reference = _Model.GetReference(currentModel.Type, ident.Value);
                    if (reference != null)
                        break;
                }

                // Restore parent context
                EntityMapping parentMapping = index == 0 && isInConstraint ? (EntityMapping)entityMappingContext.Peek() : (EntityMapping)entityMappingContext.Pop();
                Evaluant.Uss.Models.Entity parentModel =
                    index == 0 && isInConstraint ? (Evaluant.Uss.Models.Entity)entityModelContext.Peek() : (Evaluant.Uss.Models.Entity)entityModelContext.Pop();

                string cType = reference.ChildType;
                previousEntityModel = _Model.GetEntity(cType, true);

                Table parentTable = (Table)tableContext.Pop();
                SelectStatement parentQuery = (SelectStatement)queryContext.Pop();

                //	Get tree for reference.ChildType
                IList childrenSubTypes = _Model.GetTree(cType);

                // Get all fullname attributes
                StringCollection attributes = new StringCollection();
                attributes.AddRange(_Model.GetFullAttributesNames(cType));

                Hashtable subQueries = new Hashtable();

                foreach (Evaluant.Uss.Models.Entity child in childrenSubTypes)
                {
                    if (_Mapping.Entities[child.Type] == null)
                        continue;

                    string refName = ident.Value;

                    ReferenceMapping referenceMapping = parentMapping.References[refName];

                    Evaluant.Uss.Models.Entity current = Model.GetEntity(parentMapping.Type);
                    if (referenceMapping == null)
                    {
                        while (_Model.GetParent(current) != null)
                        {
                            current = Model.GetParent(current);
                            referenceMapping = _Mapping.Entities[current.Type].References[refName];
                            if (referenceMapping != null)
                                break;
                        }
                    }

                    if (referenceMapping == null)
                        throw new MappingNotFoundException(String.Format("Reference [{0}] not found in Type [{1}]", ident.Value, parentMapping.Type));

                    RuleMappingCollection ruleMapping = referenceMapping.Rules;

                    // Save child mapping context
                    EntityMapping childMapping = _Mapping.Entities[child.Type];
                    entityMappingContext.Push(childMapping);

                    entityModelContext.Push(_Model.GetEntity(child.Type));

                    // Process child mapping reference
                    ProcessEntity(ident, true);

                    // Restore child context
                    Table childTable = (Table)tableContext.Pop();
                    SelectStatement childQuery = (SelectStatement)queryContext.Pop();
                    childQuery.TableAlias = childTable.TableAlias;
                    childQuery.SelectList = new ExpressionCollection();

                    // Begin to the first INNER JOIN 
                    Table righFirstTableJoinTable = null;

                    // la référence précedente a une contrainte avec Attribute Table de type INNER JOIN
                    if (isFirstReference && parentTable.GetType() == typeof(JoinedTable))
                        righFirstTableJoinTable = parentQuery;

                        // la référence précedente suit une autre référence de type INNER JOIN
                    else if (!isFirstReference && parentTable.GetType() == typeof(JoinedTable))
                    {
                        righFirstTableJoinTable = parentTable;
                        foreach (ILogicExpression exp in parentQuery.WhereClause.SearchCondition)
                        {
                            childQuery.WhereClause.SearchCondition.Add(exp);
                        }
                    }


                        // autre cas
                    else if (parentTable.GetType() == typeof(TableSource))
                    {
                        righFirstTableJoinTable = parentTable;
                        // Ajoute les clauses Wheres de la table courante
                        if (!isInConstraint)
                            foreach (ILogicExpression exp in parentQuery.WhereClause.SearchCondition)
                            {
                                childQuery.WhereClause.SearchCondition.Add(exp);
                            }
                    }
                    else
                    {
                        righFirstTableJoinTable = parentTable;
                        if (righFirstTableJoinTable.TableAlias == null || righFirstTableJoinTable.TableAlias == string.Empty)
                            righFirstTableJoinTable.TableAlias = refName;
                    }

                    Table leftFirstJoinTable = ruleMapping.Count != 1 ? new TableSource(ruleMapping[0], ruleMapping[0].ChildTable, "rule" + index) : childTable;

                    string parentFieldTable = righFirstTableJoinTable.TableAlias;

                    for (int indexId = 0; indexId < referenceMapping.EntityParent.Ids.Count; indexId++)
                    {
                        PrimaryKeyMapping pmk = referenceMapping.EntityParent.Ids[indexId];

                        string idfield = string.Empty;
                        if (righFirstTableJoinTable.GetType() == typeof(TableSource))
                            idfield = referenceMapping.EntityParent.GetIdField(pmk);
                        else
                            idfield = referenceMapping.EntityParent.GetIdFieldAs(pmk);

                        string alias = GetParentIdAlias(referenceMapping.EntityParent, pmk.Field);
                        childQuery.SelectList.Add(new Column(ruleMapping[0], parentFieldTable, idfield, alias));
                    }

                    // Multiple Key
                    foreach (PrimaryKeyMapping pkm in childMapping.Ids)
                        childQuery.SelectList.Add(new Column(ruleMapping[ruleMapping.Count - 1], childQuery.TableAlias, childMapping.GetIdField(pkm), childMapping.GetIdFieldAs(pkm)));


                    // adds all foreign keys contained in the current table that will be used by the next reference
                    if (index + 1 < lastIndex)
                    {
                        Identifier nextIdent = path.Identifiers[index + 1];
                        Models.Entity type = child;

                        while (_Mapping.Entities[type.Type].References[nextIdent.Value] == null)
                            type = Model.GetEntity(type.Inherit, true);

                        if (_Mapping.Entities[type.Type].References[nextIdent.Value] == null)
                            break;

                        RuleMappingCollection rules = _Mapping.Entities[type.Type].References[nextIdent.Value].Rules;

                        if (rules.Count == 1
                            && rules[0].ParentField != referenceMapping.EntityParent.IdFields
                            && rules[0].ParentField != childMapping.IdFields)
                        {
                            foreach (string parentField in rules[0].ParentField.Split(SqlMapperProvider.IDSEP))
                                childQuery.SelectList.Add(new Column(rules[0], childQuery.TableAlias, parentField, parentField));


                        }
                    }

                    // specify relation role name
                    if (!string.IsNullOrEmpty(referenceMapping.DiscriminatorField))
                    {
                        childQuery.WhereClause.SearchCondition.Add(
                            new BinaryLogicExpression(
                            new Column(referenceMapping, leftFirstJoinTable.TableAlias, referenceMapping.DiscriminatorField),
                            BinaryLogicOperator.Equals,
                            new Constant(referenceMapping.DiscriminatorValue, DbType.AnsiString)
                            ));
                    }

                    // inner join on index table FK_Parent
                    JoinedTable firstJoinTable = new JoinedTable(leftFirstJoinTable, TypeJoinedTable.Inner, righFirstTableJoinTable);
                    firstJoinTable.TableAlias = leftFirstJoinTable.TableAlias;

                    for (int indexId = 0; indexId < ruleMapping[0].ParentFields.Length; indexId++)
                    {
                        string childField = ruleMapping[0].ChildFields[indexId];
                        string parentField = ruleMapping[0].ParentFields[indexId];
                        string idField = parentMapping.Ids.Count > indexId ? parentMapping.Ids[indexId].Field : string.Empty;

                        string parentid = ruleMapping[0].GetParentFieldAs();
                        if (righFirstTableJoinTable.GetType() == typeof(TableSource) || (ruleMapping.Count == 1 && parentField != idField))
                            parentid = parentField;

                        firstJoinTable.SearchConditions.Add(new BinaryLogicExpression(
                            new Column(ruleMapping[0], righFirstTableJoinTable.TableAlias, parentid),
                            BinaryLogicOperator.Equals,
                            new Column(ruleMapping[0], leftFirstJoinTable.TableAlias, childField)));
                    }

                    if (!string.IsNullOrEmpty(childMapping.DiscriminatorField))
                    {
                        BinaryLogicExpression discriminator = new BinaryLogicExpression(
                            new Column(childMapping, childQuery.TableAlias, childMapping.DiscriminatorField),
                            BinaryLogicOperator.Equals,
                            new Constant(childMapping.DiscriminatorValue, DbType.AnsiStringFixedLength)
                            );
                        childQuery.WhereClause.SearchCondition.Add(discriminator);
                    }

                    if (ruleMapping.Count == 1)
                        childQuery.FromClause.Add(firstJoinTable);

                    // Fin Construction du premier INNER JOIN 
                    if (isInConstraint && ruleMapping.Count == 1 && index == 0)
                    {
                        // Restore the first entity context
                        Table mainTable = (Table)tableContext.Peek();

                        if (ruleMapping[0].ParentFields.Length > 1)
                        {
                            MultipledKey parentKey = new MultipledKey(ruleMapping[0]);
                            MultipledKey childKey = new MultipledKey(ruleMapping[0]);
                            foreach (string key in ruleMapping[0].ParentFields)
                            {
                                parentKey.Collection.Add(new Column(ruleMapping[0], firstTable.TableAlias, key));       // parent table/column link
                                childKey.Collection.Add(new Column(ruleMapping[0], mainTable.TableAlias, key));        // child table/column link   
                            }
                            linkTableContext.Push(parentKey);       // parent table/column link
                            linkTableContext.Push(childKey);        // child table/column link
                        }
                        else
                        {
                            linkTableContext.Push(new Column(ruleMapping[0], firstTable.TableAlias, ruleMapping[0].ParentField));       // parent table/column link
                            linkTableContext.Push(new Column(ruleMapping[0], mainTable.TableAlias, ruleMapping[0].ParentField));        // child table/column link
                        }
                    }

                    tableContext.Push(firstJoinTable);

                    for (int i = 1; i < ruleMapping.Count; i++)
                    {
                        firstJoinTable = (JoinedTable)tableContext.Pop();

                        JoinedTable lastJoinTable = null;

                        // la référence courante possède une contrainte qui est de type INNER JOIN
                        if (ident.Constraint != null && childTable.GetType() == typeof(JoinedTable))
                        {
                            SelectStatement query = new SelectStatement(referenceMapping);
                            query.TableAlias = childTable.TableAlias;

                            lastJoinTable = new JoinedTable(childQuery, TypeJoinedTable.Inner, firstJoinTable);
                            lastJoinTable.TableAlias = childQuery.TableAlias;
                            lastJoinTable.SearchConditions.Add(new BinaryLogicExpression(
                                new Column(ruleMapping[i], childQuery.TableAlias, ruleMapping[i].ChildField),
                                BinaryLogicOperator.Equals,
                                new Column(ruleMapping[i], leftFirstJoinTable.TableAlias, ruleMapping[i].ParentField)));


                            query.SelectList.Add(new Column(childMapping.Ids[0], childQuery.TableAlias, childMapping.GetIdField(childMapping.Ids[0])));

                            childQuery = query;
                            tableContext.Push(lastJoinTable);
                        }
                        else
                        {
                            Table leftTable = i == ruleMapping.Count - 1 ? childTable : new TableSource(ruleMapping[i], ruleMapping[i].ChildTable, String.Concat("rule", index + i));
                            Table rightTable = firstJoinTable;

                            lastJoinTable = new JoinedTable(leftTable, TypeJoinedTable.Inner, rightTable);
                            lastJoinTable.TableAlias = leftTable.TableAlias;

                            // inner join on index table FK_Child
                            lastJoinTable.SearchConditions.Add(new BinaryLogicExpression(
                                new Column(ruleMapping[i], leftTable.TableAlias, ruleMapping[i].ChildField),
                                BinaryLogicOperator.Equals,
                                new Column(ruleMapping[i], rightTable.TableAlias, ruleMapping[i].ParentField)));

                            tableContext.Push(lastJoinTable);
                        }

                        // it's a last rule
                        if (i == ruleMapping.Count - 1)
                        {
                            lastJoinTable = (JoinedTable)tableContext.Pop();

                            if (isInConstraint && index == lastIndex - 1)
                            {
                                // Restore the first entity context
                                EntityMapping mainMapping = (EntityMapping)entityMappingContext.Peek();
                                Table mainTable = (Table)tableContext.Peek();

                                string parentField = firstMapping.GetIdField(firstMapping.Ids[0]);
                                if (path.Identifiers.Count > 1 && (!lastIsAttribute || overrideId))
                                    parentField = "ParentId";

                                linkTableContext.Push(new Column(firstMapping.Ids[0], parentTable.TableAlias, parentField));                // parent table/column link
                                linkTableContext.Push(new Column(firstMapping.Ids[0], mainTable.TableAlias, firstMapping.GetIdField(firstMapping.Ids[0])));        // child table/column link
                            }

                            if (referenceMapping.DiscriminatorField != null && referenceMapping.Name != "*")
                            {
                                BinaryLogicExpression condition = new BinaryLogicExpression(
                                    new Column(referenceMapping, leftFirstJoinTable.TableAlias, referenceMapping.DiscriminatorField),
                                    BinaryLogicOperator.Equals,
                                    new Constant(ident.Value, DbType.AnsiString));

                                collEpression.Add(condition);
                            }

                            childQuery.FromClause.Add(lastJoinTable);
                            tableContext.Push(lastJoinTable);
                        }
                    }

                    childQuery.SelectList.Insert(0, new Constant(child.Type, DbType.AnsiString, TYPE_ALIAS));

                    int attributeTableIndex = 0;

                    foreach (string attName in attributes)
                    {
                        string attNameAlias = attName.Substring(attName.LastIndexOf(DOT) + 1);
                        string shortAttName = attNameAlias;

                        AttributeMapping am = childMapping.Attributes[shortAttName];

                        // if duplicated attribute name, add an incremented index at the end  (if not already done)
                        if (!_IsAliasColumnComputed)
                        {
                            foreach (string colName in _AliasColumnMapping.Values)
                            {
                                if (colName == shortAttName)
                                {
                                    if (!_AliasColumnMapping.Contains(attName))
                                    {
                                        attNameAlias += ++_AliasColumnIndexNumber;
                                        _AliasColumnMapping.Add(attName, attNameAlias);
                                    }
                                    else
                                        attNameAlias = _AliasColumnMapping[attName].ToString();
                                    break;
                                }
                            }
                        }
                        else
                        {
                            // get the previous computed alias
                            attNameAlias = _AliasColumnMapping[attName].ToString();
                        }

                        if (am != null)
                        {
                            if (am.Table == childMapping.Table)
                            {
                                childQuery.SelectList.Add(new Column(am, childQuery.TableAlias, am.Field, attNameAlias));
                            }
                            if (am.Table != childMapping.Table && childMapping.Ids[0].Generator.Name == GeneratorMapping.GeneratorType.inherited)
                            {
                                //	Add the Left Join for parent attribute table

                                Table left = childQuery.FromClause[0];
                                Table right = new TableSource(am.ParentEntity.Ids[0], am.Table, string.Concat("a", attributeTableIndex++));

                                JoinedTable jt = new JoinedTable(left, TypeJoinedTable.LeftOuter, right);

                                jt.SearchConditions.Add(new BinaryLogicExpression(
                                    new Column(null, right.TableAlias, am.ParentField),
                                    BinaryLogicOperator.Equals,
                                    new Column(null, left.TableAlias, childMapping.GetIdField(childMapping.Ids[0]))
                                    ));

                                childQuery.FromClause[0] = jt;

                                childQuery.SelectList.Add(new Column(am, right.TableAlias, am.Field, attNameAlias));

                                //	Get the parent table and insert a clause and then we don't return the
                                //	records which have a record in a child table

                                string parentType = string.Empty;
                                if (_Model.GetParent(_Model.GetEntity(child.Type)) != null)
                                    parentType = _Model.GetParent(_Model.GetEntity(child.Type)).Type;

                                if (parentType == string.Empty)
                                    continue;

                                EntityMapping parentEntityMapping = _Mapping.Entities[parentType];

                                SelectStatement sel = (SelectStatement)subQueries[parentType];

                                SelectStatement exludeClause = new SelectStatement(null);
                                exludeClause.SelectedAllColumns = true;
                                exludeClause.FromClause.Add(new TableSource(childMapping, childMapping.Table));

                                exludeClause.WhereClause.SearchCondition.Add(new BinaryLogicExpression(
                                    new Column(parentEntityMapping.Ids[0], sel.TableAlias, parentEntityMapping.GetIdField(parentEntityMapping.Ids[0])),
                                    BinaryLogicOperator.Equals,
                                    new Column(childMapping.Ids[0], childMapping.Table, childMapping.GetIdField(childMapping.Ids[0]))));

                                ExistsPredicate ex = new ExistsPredicate(exludeClause);
                                UnaryLogicExpression ua = new UnaryLogicExpression(UnaryLogicOperator.Not, ex);

                                sel.WhereClause.SearchCondition.Add(ua);
                            }
                        }
                        else
                        {
                            childQuery.SelectList.Add(new Constant(DBNull.Value, DbType.AnsiStringFixedLength, attNameAlias));
                        }

                        // Store the correspondance between the alias/column name and the attribute name 
                        if (!_IsAliasColumnComputed && !_AliasColumnMapping.Contains(attName))
                            _AliasColumnMapping.Add(attName, attNameAlias);
                    }

                    //					entityMappingContext.Pop();
                    //					entityModelContext.Pop();
                    tableContext.Pop();

                    //childrenSubExp.SelectExpressions.Add(childQuery);
                    subQueries.Add(child.Type, childQuery);
                }

                foreach (SelectStatement sel in subQueries.Values)
                    childrenSubExp.SelectExpressions.Add(sel);

                childrenSubExp.TableAlias = parentQuery.TableAlias;

                if (parentQuery.SelectList.Count == 0)
                {
                    //parentQuery.SelectedAllColumns = true;
                }

                //isFirstReference = false;
                queryContext.Push(childrenSubExp);

                //entityMappingContext.Push(_Mapping.Entities.GetEntity(cType));

                //entityModelContext.Push(_Model.GetEntity(cType));

                //if(!isInConstraint)
                tableContext.Push(childrenSubExp);

                //				queryContext.Push(childQuery);
            }


            // if only one attribute
            if (lastIsAttribute && index == 0)
            {
                //FROM  [Course] as [e2] 
                //WHERE ([e2].[CourseId] = [e1].[CourseId])

                SelectStatement childQuery = (SelectStatement)queryContext.Pop();
                firstTable = (Table)tableContext.Pop();
                childQuery.FromClause.Add(firstTable);

                Table mainTable = (Table)tableContext.Peek();
                childQuery.WhereClause.SearchCondition.Add(
                        new BinaryLogicExpression(new Column(null, firstTable.TableAlias, firstMapping.GetIdField(firstMapping.Ids[0])),
                        BinaryLogicOperator.Equals,
                        new Column(null, mainTable.TableAlias, firstMapping.GetIdField(firstMapping.Ids[0]))));

                queryContext.Push(childQuery);
                tableContext.Push(firstTable);
            }

            if (isInConstraint)
            {
                int max = entityMappingContext.Count;
                if (lastIsAttribute)
                    max--;

                for (int i = max; i > stackCount; i--)
                {
                    entityMappingContext.Pop();
                    entityModelContext.Pop();
                }
            }
        }
Пример #6
0
		public virtual void Visit(BinaryLogicExpression expression)
		{
            bool BinaryIsFirst = _Query.Length == SELECT.Length;

            _Query.Append(OPENBRACE);

			if (IsSelectStatement(expression.LeftOperand))
				_Query.Append(OPENBRACE);
				
			expression.LeftOperand.Accept(this);

			if (IsSelectStatement(expression.LeftOperand))
				_Query.Append(CLOSEBRACE);

			Visit(expression.Operator);

			if (IsSelectStatement(expression.RightOperand))
				_Query.Append(OPENBRACE);

			expression.RightOperand.Accept(this);

			if (IsSelectStatement(expression.RightOperand))
				_Query.Append(CLOSEBRACE);

            _Query.Append(CLOSEBRACE);

            if (BinaryIsFirst)
                _Query.Append(GetDummyTableForScalarResults);
        }