internal FromClause(IDbTable firstTable, DbRelation[] orderedRelations, TableWithJoinMode[] orderedFromTablesIncludingFirstTable) { this.FromTable = firstTable; JoinClause[] joins = new JoinClause[orderedRelations.Length]; for (int relationIdx = 0; relationIdx < orderedRelations.Length; relationIdx++) { int joinedTableIdx = relationIdx + 1; joins[relationIdx] = new JoinClause(orderedRelations[relationIdx], orderedFromTablesIncludingFirstTable[joinedTableIdx].Table, orderedFromTablesIncludingFirstTable[joinedTableIdx].JoinAsOuter); } this.Joins = joins; this.JoinCount = joins.Length; }
private static string GenerateRelationsDontConnectAllTablesErrorMessage(TableWithJoinMode[] orderedFromTables) { string error = Messages.RelationBucket_NotAllTablesAreConnectedTheseAreConnected; string connectedTables = ""; foreach (TableWithJoinMode table in orderedFromTables) { if (table != null) connectedTables += " " + table.Table.Alias + ","; } if (string.IsNullOrEmpty(connectedTables)) error += " " + Messages.RelationBucket_None; else error += connectedTables.TrimEnd(','); error += "."; return error; }
private static void ThrowExceptionIfNotAllTablesAreConnected(TableWithJoinMode[] orderedFromTables) { // Make sure that all tables are connected. foreach (TableWithJoinMode joinedTable in orderedFromTables) { if (joinedTable == null) { string errorMessage = GenerateRelationsDontConnectAllTablesErrorMessage(orderedFromTables); throw new InvalidOperationException(errorMessage); } } }
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; } }