forked from nhibernate/nhibernate-core
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOneToManyJoinWalker.cs
94 lines (79 loc) · 3.73 KB
/
OneToManyJoinWalker.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
using System;
using System.Collections.Generic;
using NHibernate.Engine;
using NHibernate.Persister.Collection;
using NHibernate.Persister.Entity;
using NHibernate.SqlCommand;
using NHibernate.Util;
namespace NHibernate.Loader.Collection
{
/// <summary>
/// Walker for one-to-many associations
/// </summary>
/// <seealso cref="OneToManyLoader" />
public class OneToManyJoinWalker : CollectionJoinWalker
{
private readonly IOuterJoinLoadable elementPersister;
private readonly IQueryableCollection oneToManyPersister;
protected override bool IsDuplicateAssociation(string foreignKeyTable, string[] foreignKeyColumns)
{
//disable a join back to this same association
bool isSameJoin = oneToManyPersister.TableName.Equals(foreignKeyTable)
&& CollectionHelper.SequenceEquals<string>(foreignKeyColumns, oneToManyPersister.KeyColumnNames);
return isSameJoin || base.IsDuplicateAssociation(foreignKeyTable, foreignKeyColumns);
}
public OneToManyJoinWalker(IQueryableCollection oneToManyPersister, int batchSize, SqlString subquery,
ISessionFactoryImplementor factory, IDictionary<string, IFilter> enabledFilters)
: base(factory, enabledFilters)
{
this.oneToManyPersister = oneToManyPersister;
elementPersister = (IOuterJoinLoadable)oneToManyPersister.ElementPersister;
string alias = GenerateRootAlias(oneToManyPersister.Role);
WalkEntityTree(elementPersister, alias);
IList<OuterJoinableAssociation> allAssociations = new List<OuterJoinableAssociation>(associations);
allAssociations.Add(
new OuterJoinableAssociation(oneToManyPersister.CollectionType, null, null, alias, JoinType.LeftOuterJoin, null, Factory,
CollectionHelper.EmptyDictionary<string, IFilter>()));
InitPersisters(allAssociations, LockMode.None);
InitStatementString(elementPersister, alias, batchSize, subquery);
}
protected override string GenerateAliasForColumn(string rootAlias, string column)
{
// NH-1747 FIX (see OneToManyPersister)
return elementPersister.GenerateTableAliasForColumn(rootAlias, column);
}
private void InitStatementString(IOuterJoinLoadable elementPersister, string alias, int batchSize, SqlString subquery)
{
int joins = CountEntityPersisters(associations);
Suffixes = BasicLoader.GenerateSuffixes(joins + 1);
int collectionJoins = CountCollectionPersisters(associations) + 1;
CollectionSuffixes = BasicLoader.GenerateSuffixes(joins + 1, collectionJoins);
SqlStringBuilder whereString = WhereString(alias, oneToManyPersister.KeyColumnNames, subquery, batchSize);
string filter = oneToManyPersister.FilterFragment(alias, EnabledFilters);
whereString.Insert(0, StringHelper.MoveAndToBeginning(filter));
JoinFragment ojf = MergeOuterJoins(associations);
SqlSelectBuilder select =
new SqlSelectBuilder(Factory)
.SetSelectClause(
#pragma warning disable 618
oneToManyPersister.SelectFragment(null, null, alias, Suffixes[joins], CollectionSuffixes[0], true) +
#pragma warning restore 618
SelectString(associations))
.SetFromClause(
elementPersister.FromTableFragment(alias) + elementPersister.FromJoinFragment(alias, true, true))
.SetWhereClause(whereString.ToSqlString())
.SetOuterJoins(ojf.ToFromFragmentString,
ojf.ToWhereFragmentString + elementPersister.WhereJoinFragment(alias, true, true));
select.SetOrderByClause(OrderBy(associations, oneToManyPersister.GetSQLOrderByString(alias)));
if (Factory.Settings.IsCommentsEnabled)
{
select.SetComment("load one-to-many " + oneToManyPersister.Role);
}
SqlString = select.ToSqlString();
}
public override string ToString()
{
return GetType().FullName + '(' + oneToManyPersister.Role + ')';
}
}
}