예제 #1
0
        private bool ProcessAsTableGroupJoin(bool includeAllSubclassJoins, SqlString[] withClauseFragments, JoinFragment joinFragment)
        {
            if (!NeedsTableGroupJoin(joins, withClauseFragments, includeAllSubclassJoins))
            {
                return(false);
            }

            var    first      = joins[0];
            string joinString = ANSIJoinFragment.GetJoinString(first.JoinType);

            joinFragment.AddFromFragmentString(
                new SqlString(
                    joinString,
                    " (",
                    first.Joinable.TableName,
                    " ",
                    first.Alias
                    ));

            foreach (var join in joins)
            {
                if (join != first)
                {
                    joinFragment.AddJoin(
                        join.Joinable.TableName,
                        join.Alias,
                        join.LHSColumns,
                        JoinHelper.GetRHSColumnNames(join.AssociationType, factory),
                        join.JoinType,
                        SqlString.Empty);
                }

                AddSubclassJoins(
                    joinFragment,
                    join.Alias,
                    join.Joinable,
                    // TODO (from hibernate): Think about if this could be made always true
                    // NH Specific: made always true (original check: join.JoinType == JoinType.InnerJoin)
                    true,
                    includeAllSubclassJoins
                    );
            }

            var tableGroupWithClause = GetTableGroupJoinWithClause(withClauseFragments, first);

            joinFragment.AddFromFragmentString(tableGroupWithClause);
            return(true);
        }
예제 #2
0
        internal static bool ProcessAsTableGroupJoin(IReadOnlyList <IJoin> tableGroupJoinables, SqlString[] withClauseFragments, bool includeAllSubclassJoins, JoinFragment joinFragment, Func <string, bool> isSubclassIncluded, ISessionFactoryImplementor sessionFactoryImplementor)
        {
            if (!NeedsTableGroupJoin(tableGroupJoinables, withClauseFragments, includeAllSubclassJoins))
            {
                return(false);
            }

            var    first      = tableGroupJoinables[0];
            string joinString = ANSIJoinFragment.GetJoinString(first.JoinType);

            joinFragment.AddFromFragmentString(
                new SqlString(
                    joinString,
                    " (",
                    first.Joinable.TableName,
                    " ",
                    first.Alias
                    ));

            foreach (var join in tableGroupJoinables)
            {
                if (join != first)
                {
                    joinFragment.AddJoin(
                        join.Joinable.TableName,
                        join.Alias,
                        join.LHSColumns,
                        JoinHelper.GetRHSColumnNames(join.AssociationType, sessionFactoryImplementor),
                        join.JoinType,
                        SqlString.Empty);
                }

                bool include = includeAllSubclassJoins && isSubclassIncluded(join.Alias);
                // TODO (from hibernate): Think about if this could be made always true
                // NH Specific: made always true (original check: join.JoinType == JoinType.InnerJoin)
                const bool innerJoin = true;
                joinFragment.AddJoins(
                    join.Joinable.FromJoinFragment(join.Alias, innerJoin, include),
                    join.Joinable.WhereJoinFragment(join.Alias, innerJoin, include));
            }

            var withClause = GetTableGroupJoinWithClause(withClauseFragments, first, sessionFactoryImplementor);

            joinFragment.AddFromFragmentString(withClause);
            return(true);
        }
예제 #3
0
        /// <summary>
        /// Generate a sequence of <c>LEFT OUTER JOIN</c> clauses for the given associations.
        /// </summary>
        protected JoinFragment MergeOuterJoins(IList <OuterJoinableAssociation> associations)
        {
            JoinFragment outerjoin = Dialect.CreateOuterJoinFragment();

            var sortedAssociations        = GetSortedAssociations(associations);
            OuterJoinableAssociation last = null;

            foreach (OuterJoinableAssociation oj in sortedAssociations)
            {
                if (last != null && last.IsManyToManyWith(oj))
                {
                    oj.AddManyToManyJoin(outerjoin, (IQueryableCollection)last.Joinable);
                }
                else
                {
                    // NH Different behavior : NH1179 and NH1293
                    // Apply filters for entity joins and Many-To-One associations
                    SqlString filter = null;
                    var       enabledFiltersForJoin = oj.ForceFilter ? enabledFilters : enabledFiltersForManyToOne;
                    if (oj.ForceFilter || enabledFiltersForJoin.Count > 0)
                    {
                        string manyToOneFilterFragment = oj.Joinable.FilterFragment(oj.RHSAlias, enabledFiltersForJoin);
                        bool   joinClauseDoesNotContainsFilterAlready =
                            oj.On?.IndexOfCaseInsensitive(manyToOneFilterFragment) == -1;
                        if (joinClauseDoesNotContainsFilterAlready)
                        {
                            filter = new SqlString(manyToOneFilterFragment);
                        }
                    }

                    if (TableGroupJoinHelper.ProcessAsTableGroupJoin(new[] { oj }, new[] { oj.On, filter }, true, outerjoin, alias => true, factory))
                    {
                        continue;
                    }

                    oj.AddJoins(outerjoin);

                    // Ensure that the join condition is added to the join, not the where clause.
                    // Adding the condition to the where clause causes left joins to become inner joins.
                    if (SqlStringHelper.IsNotEmpty(filter))
                    {
                        outerjoin.AddFromFragmentString(filter);
                    }
                }
                last = oj;
            }

            return(outerjoin);
        }
        private void PrepareForIndex(QueryTranslator q)
        {
            IQueryableCollection collPersister = q.GetCollectionPersister(collectionRole);

            if (!collPersister.HasIndex)
            {
                throw new QueryException("unindexed collection before []");
            }
            string[] indexCols = collPersister.IndexColumnNames;
            if (indexCols.Length != 1)
            {
                throw new QueryException("composite-index appears in []: " + path);
            }
            string[] keyCols = collPersister.KeyColumnNames;

            JoinFragment ojf = q.CreateJoinFragment(useThetaStyleJoin);

            ojf.AddCrossJoin(collPersister.TableName, collectionName);
            ojf.AddFromFragmentString(join.ToFromFragmentString);
            if (collPersister.IsOneToMany)
            {
                IQueryable persister = (IQueryable)collPersister.ElementPersister;
                ojf.AddJoins(
                    ((IJoinable)persister).FromJoinFragment(collectionName, true, false),
                    ((IJoinable)persister).WhereJoinFragment(collectionName, true, false)
                    );
            }

            if (!continuation)
            {
                AddJoin(collPersister.TableName, collectionName, keyCols);
            }
            join.AddCondition(collectionName, indexCols, " = ");

            string[] eltCols = collPersister.ElementColumnNames;

            CollectionElement elem = new CollectionElement();

            elem.ElementColumns = StringHelper.Qualify(collectionName, eltCols);
            elem.Type           = collPersister.ElementType;
            elem.IsOneToMany    = collPersister.IsOneToMany;
            elem.Alias          = collectionName;
            elem.Join           = join;
            collectionElements.Add(elem);               //addlast
            SetExpectingCollectionIndex();

            q.AddCollection(collectionName, collectionRole);
            q.AddJoin(collectionName, ojf);
        }
예제 #5
0
        /// <summary>
        /// Generate a sequence of <c>LEFT OUTER JOIN</c> clauses for the given associations.
        /// </summary>
        protected JoinFragment MergeOuterJoins(IList <OuterJoinableAssociation> associations)
        {
            IList <OuterJoinableAssociation> sortedAssociations = new List <OuterJoinableAssociation>();

            var indices = GetTopologicalSortOrder(_dependentAliases);

            for (int index = indices.Length - 1; index >= 0; index--)
            {
                sortedAssociations.Add(associations[indices[index]]);
            }

            JoinFragment outerjoin = Dialect.CreateOuterJoinFragment();

            OuterJoinableAssociation last = null;

            foreach (OuterJoinableAssociation oj in sortedAssociations)
            {
                if (last != null && last.IsManyToManyWith(oj))
                {
                    oj.AddManyToManyJoin(outerjoin, (IQueryableCollection)last.Joinable);
                }
                else
                {
                    oj.AddJoins(outerjoin);
                    // NH Different behavior : NH1179 and NH1293
                    // Apply filters in Many-To-One association
                    if (enabledFiltersForManyToOne.Count > 0)
                    {
                        string manyToOneFilterFragment = oj.Joinable.FilterFragment(oj.RHSAlias, enabledFiltersForManyToOne);
                        bool   joinClauseDoesNotContainsFilterAlready =
                            outerjoin.ToFromFragmentString.IndexOfCaseInsensitive(manyToOneFilterFragment) == -1;
                        if (joinClauseDoesNotContainsFilterAlready)
                        {
                            // Ensure that the join condition is added to the join, not the where clause.
                            // Adding the condition to the where clause causes left joins to become inner joins.
                            outerjoin.AddFromFragmentString(new SqlString(manyToOneFilterFragment));
                        }
                    }
                }
                last = oj;
            }

            return(outerjoin);
        }