public JoinFragment ToJoinFragment( IDictionary<string, IFilter> enabledFilters, bool includeExtraJoins, string withClauseFragment, string withClauseJoinAlias) { QueryJoinFragment joinFragment = new QueryJoinFragment(factory.Dialect, useThetaStyle); if (rootJoinable != null) { joinFragment.AddCrossJoin(rootJoinable.TableName, rootAlias); string filterCondition = rootJoinable.FilterFragment(rootAlias, enabledFilters); // JoinProcessor needs to know if the where clause fragment came from a dynamic filter or not so it // can put the where clause fragment in the right place in the SQL AST. 'hasFilterCondition' keeps track // of that fact. joinFragment.HasFilterCondition = joinFragment.AddCondition(filterCondition); if (includeExtraJoins) { //TODO: not quite sure about the full implications of this! AddExtraJoins(joinFragment, rootAlias, rootJoinable, true); } } IJoinable last = rootJoinable; for (int i = 0; i < joins.Count; i++) { Join join = (Join) joins[i]; string on = join.AssociationType.GetOnCondition(join.Alias, factory, enabledFilters); string condition; if (last != null && IsManyToManyRoot(last) && ((IQueryableCollection) last).ElementType == join.AssociationType) { // the current join represents the join between a many-to-many association table // and its "target" table. Here we need to apply any additional filters // defined specifically on the many-to-many string manyToManyFilter = ((IQueryableCollection) last) .GetManyToManyFilterFragment(join.Alias, enabledFilters); condition = "".Equals(manyToManyFilter) ? on : "".Equals(on) ? manyToManyFilter : on + " and " + manyToManyFilter; } else { condition = on; } //Start NH1179 ************ //Patch reverted after NH2.0.0GA to fix some other bugs. //if (string.IsNullOrEmpty(condition)) //{ // string filterCondition = join.Joinable.FilterFragment(join.Alias, enabledFilters); // joinFragment.HasFilterCondition = joinFragment.AddCondition(filterCondition); //} //End NH1179 ************ if (withClauseFragment != null) { if (join.Alias.Equals(withClauseJoinAlias)) { condition += " and " + withClauseFragment; } } joinFragment.AddJoin( join.Joinable.TableName, join.Alias, join.LHSColumns, JoinHelper.GetRHSColumnNames(join.AssociationType, factory), join.JoinType, condition ); if (includeExtraJoins) { //TODO: not quite sure about the full implications of this! AddExtraJoins(joinFragment, join.Alias, join.Joinable, join.JoinType == JoinType.InnerJoin); } last = join.Joinable; } if (next != null) { joinFragment.AddFragment(next.ToJoinFragment(enabledFilters, includeExtraJoins)); } joinFragment.AddCondition(conditions.ToSqlString()); if (isFromPart) joinFragment.ClearWherePart(); return joinFragment; }
public JoinFragment ToJoinFragment( IDictionary<string, IFilter> enabledFilters, bool includeExtraJoins, SqlString withClauseFragment, string withClauseJoinAlias) { QueryJoinFragment joinFragment = new QueryJoinFragment(factory.Dialect, useThetaStyle); if (rootJoinable != null) { joinFragment.AddCrossJoin(rootJoinable.TableName, rootAlias); string filterCondition = rootJoinable.FilterFragment(rootAlias, enabledFilters); // JoinProcessor needs to know if the where clause fragment came from a dynamic filter or not so it // can put the where clause fragment in the right place in the SQL AST. 'hasFilterCondition' keeps track // of that fact. joinFragment.HasFilterCondition = joinFragment.AddCondition(filterCondition); if (includeExtraJoins) { //TODO: not quite sure about the full implications of this! AddExtraJoins(joinFragment, rootAlias, rootJoinable, true); } } IJoinable last = rootJoinable; for (int i = 0; i < joins.Count; i++) { Join join = joins[i]; string on = join.AssociationType.GetOnCondition(join.Alias, factory, enabledFilters); SqlString condition = new SqlString(); if (last != null && IsManyToManyRoot(last) && ((IQueryableCollection)last).ElementType == join.AssociationType) { // the current join represents the join between a many-to-many association table // and its "target" table. Here we need to apply any additional filters // defined specifically on the many-to-many string manyToManyFilter = ((IQueryableCollection)last) .GetManyToManyFilterFragment(join.Alias, enabledFilters); condition = new SqlString("".Equals(manyToManyFilter) ? on : "".Equals(on) ? manyToManyFilter : on + " and " + manyToManyFilter); } else { // NH Different behavior : NH1179 and NH1293 // Apply filters in Many-To-One association var enabledForManyToOne = FilterHelper.GetEnabledForManyToOne(enabledFilters); condition = new SqlString(string.IsNullOrEmpty(on) && enabledForManyToOne.Count > 0 ? join.Joinable.FilterFragment(join.Alias, enabledForManyToOne) : on); } if (withClauseFragment != null) { if (join.Alias.Equals(withClauseJoinAlias)) { condition = condition.Append(" and ").Append(withClauseFragment); } } // NH: the variable "condition" have to be a SqlString because it may contains Parameter instances with BackTrack joinFragment.AddJoin( join.Joinable.TableName, join.Alias, join.LHSColumns, JoinHelper.GetRHSColumnNames(join.AssociationType, factory), join.JoinType, condition ); if (includeExtraJoins) { //TODO: not quite sure about the full implications of this! AddExtraJoins(joinFragment, join.Alias, join.Joinable, join.JoinType == JoinType.InnerJoin); } last = join.Joinable; } if (next != null) { joinFragment.AddFragment(next.ToJoinFragment(enabledFilters, includeExtraJoins)); } joinFragment.AddCondition(conditions.ToSqlString()); if (isFromPart) joinFragment.ClearWherePart(); return joinFragment; }