Пример #1
0
        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;
        }
Пример #2
0
        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;
            }
        }