Skip to content

Commit 88abcf0

Browse files
author
g.yakimov
committed
improve adding of with clauses when entity overrides property from base
class
1 parent 873feec commit 88abcf0

11 files changed

+174
-5
lines changed

src/NHibernate.Test/Hql/EntityJoinHqlTest.cs

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
using System.Text.RegularExpressions;
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using System.Text.RegularExpressions;
24
using NHibernate.Cfg.MappingSchema;
5+
using NHibernate.Criterion;
36
using NHibernate.Mapping.ByCode;
47
using NHibernate.Test.Hql.EntityJoinHqlTestEntities;
58
using NUnit.Framework;
@@ -279,6 +282,43 @@ public void CrossJoinAndWithClause()
279282
}
280283
}
281284

285+
[Test]
286+
public void Join_Inheritance()
287+
{
288+
// arrange
289+
IEnumerable<int> results;
290+
var person = new PersonBase { Login = "dave", FamilyName = "grohl" };
291+
var visit_1 = new UserEntityVisit { PersonBase = person };
292+
var visit_2 = new UserEntityVisit { PersonBase = person };
293+
294+
using (ISession arrangeSession = OpenSession())
295+
using (ITransaction tx = arrangeSession.BeginTransaction())
296+
{
297+
arrangeSession.Save(person);
298+
arrangeSession.Save(visit_1);
299+
arrangeSession.Save(visit_2);
300+
arrangeSession.Flush();
301+
302+
tx.Commit();
303+
}
304+
305+
// act
306+
using (var session = OpenSession())
307+
{
308+
results = session.CreateCriteria<UserEntityVisit>()
309+
.CreateCriteria(
310+
$"{nameof(UserEntityVisit.PersonBase)}",
311+
"f",
312+
SqlCommand.JoinType.LeftOuterJoin,
313+
Restrictions.Eq("Deleted", false))
314+
.List<UserEntityVisit>()
315+
.Select(x => x.Id);
316+
}
317+
318+
// assert
319+
Assert.That(results, Is.EquivalentTo(new[] { visit_1.Id, visit_2.Id, }));
320+
}
321+
282322
#region Test Setup
283323

284324
protected override HbmMapping GetMappings()
@@ -351,6 +391,10 @@ protected override HbmMapping GetMappings()
351391
rc.Property(e => e.Name);
352392
});
353393

394+
395+
Node.AddMapping(mapper);
396+
UserEntityVisit.AddMapping(mapper);
397+
354398
return mapper.CompileMappingForAllExplicitlyAddedEntities();
355399
}
356400

src/NHibernate.Test/Hql/Node.cs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using System;
2+
using NHibernate.Mapping.ByCode;
3+
4+
namespace NHibernate.Test.Hql
5+
{
6+
public abstract class Node
7+
{
8+
private int _id;
9+
public virtual int Id
10+
{
11+
get { return _id; }
12+
set { _id = value; }
13+
}
14+
15+
public virtual bool Deleted { get; set; }
16+
public virtual string FamilyName { get; set; }
17+
18+
public static void AddMapping(ModelMapper mapper)
19+
{
20+
mapper.Class<Node>(ca =>
21+
{
22+
ca.Id(x => x.Id, map => map.Generator(Generators.Identity));
23+
ca.Property(x => x.Deleted);
24+
ca.Property(x => x.FamilyName);
25+
ca.Table("Node");
26+
ca.Abstract(true);
27+
});
28+
29+
mapper.JoinedSubclass<PersonBase>(ca =>
30+
{
31+
ca.Key(x => x.Column("FK_Node_ID"));
32+
ca.Extends(typeof(Node));
33+
ca.Property(x => x.Deleted);
34+
ca.Property(x => x.Login);
35+
});
36+
}
37+
}
38+
39+
[Serializable]
40+
public class PersonBase : Node
41+
{
42+
public virtual string Login { get; set; }
43+
public override bool Deleted { get; set; }
44+
}
45+
46+
[Serializable]
47+
public class UserEntityVisit
48+
{
49+
private int _id;
50+
public virtual int Id
51+
{
52+
get { return _id; }
53+
set { _id = value; }
54+
}
55+
56+
public virtual bool Deleted { get; set; }
57+
58+
private PersonBase _PersonBase;
59+
public virtual PersonBase PersonBase
60+
{
61+
get { return _PersonBase; }
62+
set { _PersonBase = value; }
63+
}
64+
65+
public static void AddMapping(ModelMapper mapper)
66+
{
67+
mapper.Class<UserEntityVisit>(ca =>
68+
{
69+
ca.Id(x => x.Id, map => map.Generator(Generators.Identity));
70+
ca.Property(x => x.Deleted);
71+
ca.ManyToOne(x => x.PersonBase);
72+
});
73+
}
74+
}
75+
}

src/NHibernate/Hql/Ast/ANTLR/Tree/ComponentJoin.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,11 @@ public bool TryToType(string propertyName, out IType type)
150150
return fromElementType.GetBasePropertyMapping().TryToType(GetPropertyPath(propertyName), out type);
151151
}
152152

153+
public string[] ToColumns(ICriteria pathCriteria, string propertyName, Func<ICriteria, string> getSQLAlias)
154+
{
155+
return fromElementType.GetBasePropertyMapping().ToColumns(pathCriteria, GetPropertyPath(propertyName), getSQLAlias);
156+
}
157+
153158
public string[] ToColumns(string alias, string propertyName)
154159
{
155160
return fromElementType.GetBasePropertyMapping().ToColumns(alias, GetPropertyPath(propertyName));

src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ private bool TryGetColumns(ICriteria subcriteria, string path, bool verifyProper
766766
return false;
767767
}
768768

769-
columns = propertyMapping.ToColumns(GetSQLAlias(pathCriteria), propertyName);
769+
columns = propertyMapping.ToColumns(pathCriteria, propertyName, GetSQLAlias);
770770
return true;
771771
}
772772

src/NHibernate/Persister/Collection/AbstractCollectionPersister.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,12 @@ public bool IsManyToManyFiltered(IDictionary<string, IFilter> enabledFilters)
13861386
return IsManyToMany && (manyToManyWhereString != null || manyToManyFilterHelper.IsAffectedBy(enabledFilters));
13871387
}
13881388

1389+
public string[] ToColumns(ICriteria pathCriteria, string propertyName, Func<ICriteria, string> getSQLAlias)
1390+
{
1391+
string alias = getSQLAlias(pathCriteria);
1392+
return ToColumns(alias, propertyName);
1393+
}
1394+
13891395
public string[] ToColumns(string alias, string propertyName)
13901396
{
13911397
if ("index".Equals(propertyName))

src/NHibernate/Persister/Collection/CollectionPropertyMapping.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,12 @@ public bool TryToType(string propertyName, out IType type)
5757
}
5858
}
5959

60+
public string[] ToColumns(ICriteria pathCriteria, string propertyName, Func<ICriteria, string> getSQLAlias)
61+
{
62+
string alias = getSQLAlias(pathCriteria);
63+
return ToColumns(alias, propertyName);
64+
}
65+
6066
public string[] ToColumns(string alias, string propertyName)
6167
{
6268
string[] cols;
@@ -117,4 +123,4 @@ public IType Type
117123
get { return memberPersister.CollectionType; }
118124
}
119125
}
120-
}
126+
}

src/NHibernate/Persister/Collection/ElementPropertyMapping.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ public bool TryToType(string propertyName, out IType outType)
4747
}
4848
}
4949

50+
public string[] ToColumns(ICriteria pathCriteria, string propertyName, Func<ICriteria, string> getSQLAlias)
51+
{
52+
string alias = getSQLAlias(pathCriteria);
53+
return ToColumns(alias, propertyName);
54+
}
55+
5056
public string[] ToColumns(string alias, string propertyName)
5157
{
5258
if (propertyName == null || "id".Equals(propertyName))
@@ -71,4 +77,4 @@ public IType Type
7177

7278
#endregion
7379
}
74-
}
80+
}

src/NHibernate/Persister/Entity/AbstractEntityPersister.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2050,6 +2050,11 @@ public virtual string GetRootTableAlias(string drivingAlias)
20502050
return drivingAlias;
20512051
}
20522052

2053+
public virtual string[] ToColumns(ICriteria pathCriteria, string propertyName, Func<ICriteria, string> getSQLAlias)
2054+
{
2055+
return propertyMapping.ToColumns(pathCriteria, propertyName, getSQLAlias);
2056+
}
2057+
20532058
public virtual string[] ToColumns(string alias, string propertyName)
20542059
{
20552060
return propertyMapping.ToColumns(alias, propertyName);

src/NHibernate/Persister/Entity/AbstractPropertyMapping.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ public bool TryToType(string propertyName, out IType type)
4444
return typesByPropertyPath.TryGetValue(propertyName, out type);
4545
}
4646

47+
public virtual string[] ToColumns(ICriteria pathCriteria, string propertyName, Func<ICriteria, string> getSQLAlias)
48+
{
49+
string alias = getSQLAlias(pathCriteria);
50+
return ToColumns(alias, propertyName);
51+
}
52+
4753
public virtual string[] ToColumns(string alias, string propertyName)
4854
{
4955
//TODO: *two* hashmap lookups here is one too many...

src/NHibernate/Persister/Entity/BasicEntityPropertyMapping.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1+
using System;
2+
using NHibernate.Criterion;
13
using NHibernate.Type;
4+
using static NHibernate.Impl.CriteriaImpl;
25

36
namespace NHibernate.Persister.Entity
47
{
@@ -26,6 +29,17 @@ public override IType Type
2629
get { return persister.Type; }
2730
}
2831

32+
public override string[] ToColumns(ICriteria pathCriteria, string propertyName, Func<ICriteria, string> getSQLAlias)
33+
{
34+
var withClause = pathCriteria as Subcriteria != null ? ((Subcriteria) pathCriteria).WithClause as SimpleExpression : null;
35+
if (withClause != null && withClause.PropertyName == propertyName)
36+
{
37+
return base.ToColumns(persister.GenerateTableAlias(getSQLAlias(pathCriteria), 0), propertyName);
38+
}
39+
40+
return base.ToColumns(pathCriteria, propertyName, getSQLAlias);
41+
}
42+
2943
public override string[] ToColumns(string alias, string propertyName)
3044
{
3145
return

src/NHibernate/Persister/Entity/IPropertyMapping.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ public interface IPropertyMapping
2929
/// <returns>true if a type was found, false if not</returns>
3030
bool TryToType(string propertyName, out IType type);
3131

32+
string[] ToColumns(ICriteria pathCriteria, string propertyName, System.Func<ICriteria, string> getSQLAlias);
33+
3234
/// <summary>
3335
/// Given a query alias and a property path, return the qualified column name
3436
/// </summary>
@@ -40,4 +42,4 @@ public interface IPropertyMapping
4042
/// <summary> Given a property path, return the corresponding column name(s).</summary>
4143
string[] ToColumns(string propertyName);
4244
}
43-
}
45+
}

0 commit comments

Comments
 (0)