Exemple #1
0
        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;
            }
        }