Skip to content

Commit dce3d6e

Browse files
committed
Fix Order By for composite property projection in Criteria
1 parent b734d00 commit dce3d6e

File tree

5 files changed

+68
-15
lines changed

5 files changed

+68
-15
lines changed

src/NHibernate.Test/Async/CompositeId/ClassWithCompositeIdFixture.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,5 +239,33 @@ public async Task HqlAsync()
239239
Assert.AreEqual(1, results.Count);
240240
}
241241
}
242+
243+
//NH-2926 (GH-1103)
244+
[Test]
245+
public async Task QueryOverOrderByIdProjectionDoesntThrowAsync()
246+
{
247+
// insert the new objects
248+
using (ISession s = OpenSession())
249+
using (ITransaction t = s.BeginTransaction())
250+
{
251+
ClassWithCompositeId theClass = new ClassWithCompositeId(id);
252+
theClass.OneProperty = 5;
253+
254+
ClassWithCompositeId theSecondClass = new ClassWithCompositeId(secondId);
255+
theSecondClass.OneProperty = 10;
256+
257+
await (s.SaveAsync(theClass));
258+
await (s.SaveAsync(theSecondClass));
259+
260+
await (t.CommitAsync());
261+
}
262+
263+
using (ISession s = OpenSession())
264+
{
265+
var results = await (s.QueryOver<ClassWithCompositeId>().Select(Projections.Id()).OrderBy(Projections.Id()).Desc.ListAsync<Id>());
266+
Assert.That(results.Count, Is.EqualTo(2));
267+
}
268+
}
269+
242270
}
243271
}

src/NHibernate.Test/CompositeId/ClassWithCompositeIdFixture.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,5 +228,33 @@ public void Hql()
228228
Assert.AreEqual(1, results.Count);
229229
}
230230
}
231+
232+
//NH-2926 (GH-1103)
233+
[Test]
234+
public void QueryOverOrderByIdProjectionDoesntThrow()
235+
{
236+
// insert the new objects
237+
using (ISession s = OpenSession())
238+
using (ITransaction t = s.BeginTransaction())
239+
{
240+
ClassWithCompositeId theClass = new ClassWithCompositeId(id);
241+
theClass.OneProperty = 5;
242+
243+
ClassWithCompositeId theSecondClass = new ClassWithCompositeId(secondId);
244+
theSecondClass.OneProperty = 10;
245+
246+
s.Save(theClass);
247+
s.Save(theSecondClass);
248+
249+
t.Commit();
250+
}
251+
252+
using (ISession s = OpenSession())
253+
{
254+
var results = s.QueryOver<ClassWithCompositeId>().Select(Projections.Id()).OrderBy(Projections.Id()).Desc.List<Id>();
255+
Assert.That(results.Count, Is.EqualTo(2));
256+
}
257+
}
258+
231259
}
232260
}

src/NHibernate/Criterion/CriterionUtil.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ public static SqlString[] GetColumnNamesForSimpleExpression(
4646

4747
internal static SqlString[] GetColumnNamesUsingProjection(IProjection projection, ICriteriaQuery criteriaQuery, ICriteria criteria)
4848
{
49+
if (projection is IPropertyProjection propertyProjection)
50+
{
51+
return GetColumnNamesUsingPropertyName(criteriaQuery, criteria, propertyProjection.PropertyName);
52+
}
53+
4954
SqlString sqlString = projection.ToSqlString(criteria,
5055
criteriaQuery.GetIndexForAlias(),
5156
criteriaQuery);

src/NHibernate/Criterion/IdentifierProjection.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
using System;
2+
using NHibernate.Persister.Entity;
23
using NHibernate.SqlCommand;
34
using NHibernate.Type;
4-
using NHibernate.Util;
55

66
namespace NHibernate.Criterion
77
{
88
[Serializable]
9-
public class IdentifierProjection : SimpleProjection
9+
public class IdentifierProjection : SimpleProjection, IPropertyProjection
1010
{
1111
private bool grouped;
1212

@@ -21,7 +21,7 @@ protected internal IdentifierProjection() : this(false)
2121

2222
public override string ToString()
2323
{
24-
return "id";
24+
return PropertyName;
2525
}
2626

2727
public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery)
@@ -66,5 +66,7 @@ public override SqlString ToGroupSqlString(ICriteria criteria, ICriteriaQuery cr
6666
}
6767
return new SqlString(string.Join(",", criteriaQuery.GetIdentifierColumns(criteria)));
6868
}
69+
70+
public string PropertyName => EntityPersister.EntityID;
6971
}
7072
}

src/NHibernate/Criterion/Order.cs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,8 @@ public Order(string propertyName, bool ascending)
3838
/// </summary>
3939
public virtual SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery)
4040
{
41-
if (projection != null)
42-
{
43-
SqlString sb = SqlString.Empty;
44-
SqlString produced = this.projection.ToSqlString(criteria, 0, criteriaQuery);
45-
SqlString truncated = SqlStringHelper.RemoveAsAliasesFromSql(produced);
46-
sb = sb.Append(truncated);
47-
sb = sb.Append(ascending ? " asc" : " desc");
48-
return sb;
49-
}
50-
51-
string[] columns = criteriaQuery.GetColumnAliasesUsingProjection(criteria, propertyName);
52-
Type.IType type = criteriaQuery.GetTypeUsingProjection(criteria, propertyName);
41+
SqlString[] columns = CriterionUtil.GetColumnNames(propertyName, projection, criteriaQuery, criteria);
42+
Type.IType type = projection?.GetTypes(criteria, criteriaQuery)[0] ?? criteriaQuery.GetTypeUsingProjection(criteria, propertyName);
5343

5444
StringBuilder fragment = new StringBuilder();
5545
ISessionFactoryImplementor factory = criteriaQuery.Factory;

0 commit comments

Comments
 (0)