Skip to content

Commit 8d13f24

Browse files
bahusoidhazzik
authored andcommitted
Fix unexpected order by clause in a criteria with projections
Fixes #1206
1 parent ad676cc commit 8d13f24

File tree

3 files changed

+185
-1
lines changed

3 files changed

+185
-1
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System;
12+
using System.Collections.Generic;
13+
using NHibernate.Cfg.MappingSchema;
14+
using NHibernate.Criterion;
15+
using NHibernate.Mapping.ByCode;
16+
using NHibernate.SqlCommand;
17+
using NUnit.Framework;
18+
19+
namespace NHibernate.Test.NHSpecificTest.NH1761
20+
{
21+
using System.Threading.Tasks;
22+
[TestFixture]
23+
public class ByCodeFixtureAsync : TestCaseMappingByCode
24+
{
25+
protected override HbmMapping GetMappings()
26+
{
27+
var mapper = new ModelMapper();
28+
mapper.Class<FundingCategory>(rc =>
29+
{
30+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
31+
rc.Property(x => x.Name);
32+
rc.Bag(x => x.FundingPrograms, m => {}, r => r.OneToMany());
33+
34+
});
35+
mapper.Class<FundingProgram>(rc =>
36+
{
37+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
38+
rc.ManyToOne(x => x.Recipient);
39+
rc.Property(x => x.ObligatedAmount);
40+
rc.Bag(x => x.Projects, m => { m.OrderBy("Name asc"); }, r => r.OneToMany());
41+
});
42+
mapper.Class<Project>(rc =>
43+
{
44+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
45+
rc.ManyToOne(x => x.Recipient);
46+
rc.Property(x => x.ObligatedAmount);
47+
});
48+
mapper.Class<Recipient>(rc =>
49+
{
50+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
51+
});
52+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
53+
}
54+
55+
[Test]
56+
public async Task InvalidOrderByClauseAsync()
57+
{
58+
using (var session = OpenSession())
59+
{
60+
var recipientId = Guid.NewGuid();
61+
await (session.CreateCriteria(typeof(FundingCategory), "fc")
62+
.CreateCriteria("FundingPrograms", "fp")
63+
.CreateCriteria("Projects", "p", JoinType.LeftOuterJoin)
64+
.Add(
65+
Restrictions.Disjunction()
66+
.Add(Restrictions.Eq("fp.Recipient.Id", recipientId))
67+
.Add(Restrictions.Eq("p.Recipient.Id", recipientId))
68+
)
69+
.SetProjection(
70+
Projections.ProjectionList()
71+
.Add(Projections.GroupProperty("fc.Name"), "fcn")
72+
.Add(Projections.Sum("fp.ObligatedAmount"), "fpo")
73+
.Add(Projections.Sum("p.ObligatedAmount"), "po")
74+
)
75+
.AddOrder(Order.Desc("fpo"))
76+
.AddOrder(Order.Desc("po"))
77+
.AddOrder(Order.Asc("fcn"))
78+
.ListAsync<object[]>());
79+
}
80+
}
81+
}
82+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using NHibernate.Cfg.MappingSchema;
4+
using NHibernate.Criterion;
5+
using NHibernate.Mapping.ByCode;
6+
using NHibernate.SqlCommand;
7+
using NUnit.Framework;
8+
9+
namespace NHibernate.Test.NHSpecificTest.NH1761
10+
{
11+
[TestFixture]
12+
public class ByCodeFixture : TestCaseMappingByCode
13+
{
14+
protected override HbmMapping GetMappings()
15+
{
16+
var mapper = new ModelMapper();
17+
mapper.Class<FundingCategory>(rc =>
18+
{
19+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
20+
rc.Property(x => x.Name);
21+
rc.Bag(x => x.FundingPrograms, m => {}, r => r.OneToMany());
22+
23+
});
24+
mapper.Class<FundingProgram>(rc =>
25+
{
26+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
27+
rc.ManyToOne(x => x.Recipient);
28+
rc.Property(x => x.ObligatedAmount);
29+
rc.Bag(x => x.Projects, m => { m.OrderBy("Name asc"); }, r => r.OneToMany());
30+
});
31+
mapper.Class<Project>(rc =>
32+
{
33+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
34+
rc.ManyToOne(x => x.Recipient);
35+
rc.Property(x => x.ObligatedAmount);
36+
});
37+
mapper.Class<Recipient>(rc =>
38+
{
39+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
40+
});
41+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
42+
}
43+
44+
[Test]
45+
public void InvalidOrderByClause()
46+
{
47+
using (var session = OpenSession())
48+
{
49+
var recipientId = Guid.NewGuid();
50+
session.CreateCriteria(typeof(FundingCategory), "fc")
51+
.CreateCriteria("FundingPrograms", "fp")
52+
.CreateCriteria("Projects", "p", JoinType.LeftOuterJoin)
53+
.Add(
54+
Restrictions.Disjunction()
55+
.Add(Restrictions.Eq("fp.Recipient.Id", recipientId))
56+
.Add(Restrictions.Eq("p.Recipient.Id", recipientId))
57+
)
58+
.SetProjection(
59+
Projections.ProjectionList()
60+
.Add(Projections.GroupProperty("fc.Name"), "fcn")
61+
.Add(Projections.Sum("fp.ObligatedAmount"), "fpo")
62+
.Add(Projections.Sum("p.ObligatedAmount"), "po")
63+
)
64+
.AddOrder(Order.Desc("fpo"))
65+
.AddOrder(Order.Desc("po"))
66+
.AddOrder(Order.Asc("fcn"))
67+
.List<object[]>();
68+
}
69+
}
70+
}
71+
72+
public class FundingCategory
73+
{
74+
public virtual Guid Id { get; set; }
75+
public virtual string Name { get; set; }
76+
public virtual IList<FundingProgram> FundingPrograms { get; set; } = new List<FundingProgram>();
77+
78+
}
79+
80+
public class FundingProgram
81+
{
82+
public virtual Guid Id { get; set; }
83+
public virtual Recipient Recipient { get; set; }
84+
public virtual decimal ObligatedAmount { get; set; }
85+
public virtual IList<Project> Projects { get; set; } = new List<Project>();
86+
}
87+
88+
public class Project
89+
{
90+
public virtual Guid Id { get; set; }
91+
public virtual Recipient Recipient { get; set; }
92+
public virtual decimal ObligatedAmount { get; set; }
93+
}
94+
95+
public class Recipient
96+
{
97+
public virtual Guid Id { get; set; }
98+
}
99+
}

src/NHibernate/Loader/AbstractEntityJoinWalker.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,10 @@ private void InitStatementString(OuterJoinableAssociation rootAssociation, SqlSt
126126
.SetFromClause(Dialect.AppendLockHint(lockMode, persister.FromTableFragment(alias)) +persister.FromJoinFragment(alias, true, true))
127127
.SetWhereClause(condition)
128128
.SetOuterJoins(ojf.ToFromFragmentString,ojf.ToWhereFragmentString + WhereFragment)
129-
.SetOrderByClause(OrderBy(associations, orderBy))
129+
.SetOrderByClause(
130+
projection == null
131+
? OrderBy(associations, orderBy)
132+
: orderBy)
130133
.SetGroupByClause(groupBy)
131134
.SetHavingClause(having);
132135

0 commit comments

Comments
 (0)