public override void Visit (UnionStatement unionStatement) { VisitUnion (unionStatement, false); }
void VisitUnion (UnionStatement unionStatement, bool parenthesize) { foreach (SelectStatement query in unionStatement.SelectExpressions) { if (parenthesize) { _Query.Append (" ( "); query.Accept (this); _Query.Append (" ) "); } else query.Accept (this); if (unionStatement.SelectExpressions.IndexOf (query) != unionStatement.SelectExpressions.Count - 1) _Query.Append ("UNION "); } if (unionStatement.OrderByClause != null) unionStatement.OrderByClause.Accept (this); }
/// <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(); } } }
public ISQLExpression TransformToSql(Path path, string[] attributes, string[] orderby, bool lastIsAttribute) { // Get all the entity of the hierarchy (parent and children) string baseType = path.Identifiers[0].Value; IList tree = _Model.GetTree(baseType); _UserAttributes = new StringCollection(); // attributes == null => don't get attributes if (attributes != null) { // Get the specified class and store all the inherited classes Evaluant.Uss.Models.Entity parent = null; Evaluant.Uss.Models.EntityCollection parents = new Evaluant.Uss.Models.EntityCollection(); if (path.Identifiers.Count == 1) parent = _Model.GetEntity(path.Identifiers[0].Value); else { string refName = path.Identifiers[path.Identifiers.Count - 1].Value; string firstType = path.Identifiers[0].Value; string lastType = firstType; string nextRefName = string.Empty; for (int i = 0; i < path.Identifiers.Count - 1; i++) { nextRefName = path.Identifiers[i + 1].Value; // The next identifier isn't a reference but an attribute if (_Model.GetReference(lastType, nextRefName) == null && _Model.GetAttribute(lastType, nextRefName) != null) continue; lastType = _Model.GetReference(lastType, nextRefName, true).ChildType; } parent = _Model.GetEntity(lastType); } if (parent == null) throw new Evaluant.Uss.Models.ModelElementNotFoundException(String.Format("The type [{0}] was not found. Check your metadata.", baseType)); if (attributes.Length == 0) { // attributes.Length == 0 => get all attributes _UserAttributes.AddRange(_Model.GetFullAttributesNames(parent.Type)); } else { // attributes.Length > 0 => get the user defined attributes foreach (string attName in attributes) { _UserAttributes.Add(_Model.GetFullAttributeName(attName, parent.Type)); } } } UnionStatement sqlQuery = new UnionStatement(); // Process each entity of the tree and put the corresponding sql query // into a UnionStatement StringCollection processedTables = new StringCollection(); _BaseType = path.Identifiers[0].Value; Hashtable expressions = new Hashtable(); string commonIdField = string.Empty; foreach (Evaluant.Uss.Models.Entity entity in tree) { // If the entity doesn't have a mapping => don't process it if (_Mapping.Entities[entity.Type] == null) continue; path.Identifiers[0].Value = entity.Type; EntityMapping entityMapping = _Mapping.Entities[entity.Type]; if (processedTables.Contains(entityMapping.Table)) continue; processedTables.Add(entityMapping.Table); _ExprLevel.Push(PATH); SelectStatement exp = (SelectStatement)TransformToSql(path, _UserAttributes, true, lastIsAttribute); _ExprLevel.Pop(); // process alias name calculation only once _IsAliasColumnComputed = true; expressions.Add(entity.Type, exp); string parentType = string.Empty; if (_Model.GetParent(_Model.GetEntity(entity.Type)) != null) parentType = _Model.GetParent(_Model.GetEntity(entity.Type)).Type; if (parentType == string.Empty || entityMapping.Ids[0].Generator.Name != GeneratorMapping.GeneratorType.inherited || parentType != _BaseType) continue; EntityMapping parentMapping = _Mapping.Entities[parentType]; SelectStatement sel = (SelectStatement)expressions[parentType]; SelectStatement exludeClause = new SelectStatement(null); exludeClause.SelectedAllColumns = true; exludeClause.FromClause.Add(new TableSource(entityMapping, entityMapping.Table)); string parentIdField = parentMapping.GetIdField(parentMapping.Ids[0]); if (path.Identifiers.Count > 1) parentIdField = "ParentId"; exludeClause.WhereClause.SearchCondition.Add(new BinaryLogicExpression( new Column(parentMapping.Ids[0], sel.TableAlias, parentIdField), BinaryLogicOperator.Equals, new Column(entityMapping.Ids[0], entityMapping.Table, entityMapping.GetIdField(entityMapping.Ids[0])))); ExistsPredicate ex = new ExistsPredicate(exludeClause); UnaryLogicExpression ua = new UnaryLogicExpression(UnaryLogicOperator.Not, ex); sel.WhereClause.SearchCondition.Add(ua); //sqlQuery.SelectExpressions.Add(exp); } //If there are many tables in the union statement, make the id fields aliases identical bool isFirstSelect = true; ArrayList idAliases = new ArrayList(); foreach (ISQLExpression exp in expressions.Values) { SelectStatement innerSelect = (SelectStatement)exp; if (isFirstSelect) { foreach (ISQLExpression innerExp in innerSelect.SelectList) { if (innerExp is Column && ((Column)innerExp).Alias.StartsWith(EntityMapping.PREFIX_ID)) idAliases.Add(((Column)innerExp).Alias); } isFirstSelect = false; } else { int i = 0; foreach (ISQLExpression innerExp in innerSelect.SelectList) { if (innerExp is Column && ((Column)innerExp).Alias.StartsWith(EntityMapping.PREFIX_ID)) { if (idAliases.Count > i) ((Column)innerExp).Alias = (string)idAliases[i]; else throw new UniversalStorageException(string.Format("entity Id fields do not meet the one of its parent '{0}'", _BaseType)); i++; } } } //Add the SelectStatement to the unionStatement sqlQuery.SelectExpressions.Add(innerSelect); } if (entityMappingContext.Count == 0) { throw new MappingNotFoundException(String.Format("Type not found [{0}]", baseType)); } EntityMapping em = (EntityMapping)entityMappingContext.Peek(); if (orderby != null) { for (int i = 0; i < orderby.Length; i++) { string order = orderby[i].Trim(); if (order != string.Empty) { bool isDesc = false; OrderByClauseColumn col = null; int indexOfDirection = 0; if ((indexOfDirection = order.ToLower().IndexOf(" desc")) > 0) { order = order.Substring(0, indexOfDirection).Trim(); isDesc = true; } else if ((indexOfDirection = order.ToLower().IndexOf(" asc")) > 0) order = order.Substring(0, indexOfDirection).Trim(); if (order == "Id") { col = new OrderByClauseColumn(em.GetIdField(em.Ids[0]), true); } else { AttributeMapping orderMapping = em.Attributes[order, true]; string orderColName = orderMapping.Name; string fullAttributeName = _Model.GetFullAttributeName(orderMapping.Name, orderMapping.ParentEntity.Type); if (_AliasColumnMapping.Contains(fullAttributeName)) orderColName = _AliasColumnMapping[fullAttributeName].ToString(); col = new OrderByClauseColumn(orderColName, isDesc); } sqlQuery.OrderByClause.Add(col); } } } if (sqlQuery.OrderByClause.Count == 0 && !lastIsAttribute && orderby != null) { // Id position = 1 if loading single Entity (Person or Person[Name = 'p1'] // Id position = 2 if loading referenced Entity (Person.Partners or Person[Name = 'p1'].Partners) int idPosition = (path.Identifiers.Count == 1) ? 1 : 2; if (idPosition == 2) idPosition = _Mapping.Entities[path.Identifiers[0].Value].Ids.Count + 1; Column columnId = (Column)sqlQuery.SelectExpressions[0].SelectList[idPosition]; // get the Id alias of the first SelectStatement in case of UnionStatement if (sqlQuery.SelectExpressions[0] is UnionStatement) { columnId = (Column)((UnionStatement)sqlQuery.SelectExpressions[0]).SelectExpressions[0].SelectList[idPosition]; } EntityMapping entityMap = null; if (columnId.TagMapping is PrimaryKeyMapping) entityMap = ((PrimaryKeyMapping)columnId.TagMapping).ParentEntity; if (columnId.TagMapping is RuleMapping) { if (idPosition == 2) entityMap = _Mapping.Entities[((RuleMapping)columnId.TagMapping).ParentReference.EntityChild]; else entityMap = ((RuleMapping)columnId.TagMapping).ParentReference.EntityParent; } if (entityMap != null) { SelectStatement selectQuery = sqlQuery; if (sqlQuery is UnionStatement && ((UnionStatement)sqlQuery).SelectExpressions.Count > 0) selectQuery = ((UnionStatement)sqlQuery).SelectExpressions[0] as SelectStatement; foreach (PrimaryKeyMapping pkm in entityMap.Ids) { OrderByClauseColumn orderCol = null; foreach (ISQLExpression exp in selectQuery.SelectList) { if (exp is Column && exp.TagMapping == pkm) { Column col = exp as Column; orderCol = new OrderByClauseColumn(col.Alias); break; } } if (orderCol == null) { AttributeMapping attribute = entityMap.Attributes.FindByField(pkm.Field); string idFieldAlias = pkm.ParentEntity.GetIdFieldAs(pkm); foreach (string alias in _AliasColumnMapping.Keys) { if (alias.Contains(".") && attribute != null) { if (alias.Split('.')[1] == attribute.Name) { orderCol = new OrderByClauseColumn(_AliasColumnMapping[alias].ToString()); break; } } else if (alias == idFieldAlias) { orderCol = new OrderByClauseColumn(_AliasColumnMapping[alias].ToString()); break; } } if (orderCol == null) orderCol = new OrderByClauseColumn(em.GetIdFieldAs(pkm)); } if (orderCol != null) sqlQuery.OrderByClause.Add(orderCol); } } } return sqlQuery; }
public override void Visit(UnionStatement unionStatement) { if (unionStatement.OrderByClause != null && unionStatement.OrderByClause.Count > 0) _Query.Append(SELECT).Append(MULT).Append(FROM).Append(OPENBRACE); foreach (SelectStatement query in unionStatement.SelectExpressions) { query.Accept(this); if (unionStatement.SelectExpressions.IndexOf(query) != unionStatement.SelectExpressions.Count - 1) _Query.Append(UNIONALL); } if (unionStatement.OrderByClause != null && unionStatement.OrderByClause.Count > 0) _Query.Append(CLOSEBRACE); if (unionStatement.OrderByClause != null) unionStatement.OrderByClause.Accept(this); }
public virtual void Visit(UnionStatement unionStatement) { foreach(SelectStatement query in unionStatement.SelectExpressions) { query.Accept(this); if (unionStatement.SelectExpressions.IndexOf(query) != unionStatement.SelectExpressions.Count - 1) _Query.Append(UNIONALL); } if( unionStatement.OrderByClause != null) unionStatement.OrderByClause.Accept(this); }