private static bool GetNextRelationAndTable(DbRelationCollection allRelations, List<JoinMode> allJoinModes, TableWithJoinMode[] usedTables, out DbRelation nextRelation, out TableWithJoinMode nextTable) { nextRelation = null; nextTable = null; for (int idxRelation = 0; idxRelation < allRelations.Count; idxRelation++) { DbRelation currentRelation = allRelations[idxRelation]; IDbTable newTableCandidate = null; TableWithJoinMode alreadyUsedTableFromCurrentRelation = null; bool connectAsOuter = false; int numOfTablesCurrentRelationConnects = 0; // Check how many of the used tables current relation connects. for (int idxTable = 0; idxTable < usedTables.Length; idxTable++) { if (usedTables[idxTable] == null) continue; if (currentRelation.Parent.HasEqualAliasAndNameAs(usedTables[idxTable].Table)) { // Parent table is already in the ordered from tables list. numOfTablesCurrentRelationConnects++; newTableCandidate = currentRelation.Child; alreadyUsedTableFromCurrentRelation = usedTables[idxTable]; if (allJoinModes[idxRelation].ChildrenAsOuter == true) connectAsOuter = true; } if (currentRelation.Child.HasEqualAliasAndNameAs(usedTables[idxTable].Table)) { // Child table is already in the ordered from tables list. numOfTablesCurrentRelationConnects++; newTableCandidate = currentRelation.Parent; alreadyUsedTableFromCurrentRelation = usedTables[idxTable]; if (allJoinModes[idxRelation].ParentAsOuter == true) connectAsOuter = true; } } // If current relation connects only one used table than the other one is a new table. // Return the new relation and table. if (numOfTablesCurrentRelationConnects == 1) { // If the already used table is connected as outer then the new one MUST be outer, too. if (alreadyUsedTableFromCurrentRelation.JoinAsOuter == true) connectAsOuter = true; nextRelation = currentRelation; nextTable = new TableWithJoinMode(newTableCandidate, connectAsOuter); return true; } } return false; }
private static void SortRelationsAndJoinModes(DbRelationCollection allRelations, List<JoinMode> allJoinModes, IDbTable firstTable, out DbRelation[] orderedRelations, out TableWithJoinMode[] orderedFromTables) { // Sorts relations in a fashion so that only INNER and LEFT OUTER joins are used. RIGHT joins will never be required. orderedRelations = new DbRelation[allRelations.Count]; int relationIdx = 0; orderedFromTables = new TableWithJoinMode[allJoinModes.Count + 1]; int fromIdx = 0; // JoinAsOuter property doesn't doesn't affect 1st table. orderedFromTables[fromIdx] = new TableWithJoinMode(firstTable, false); fromIdx++; DbRelation nextRelation; TableWithJoinMode nextTable; while (GetNextRelationAndTable(allRelations, allJoinModes, orderedFromTables, out nextRelation, out nextTable)) { orderedRelations[relationIdx++] = nextRelation; orderedFromTables[fromIdx++] = nextTable; } }