Skip to content

Commit 25bc518

Browse files
authored
Support basic arithmetic operations (+, -, *, /) in QueryOver (#2156)
1 parent 708ae88 commit 25bc518

File tree

4 files changed

+180
-58
lines changed

4 files changed

+180
-58
lines changed

src/NHibernate.Test/Async/Criteria/Lambda/IntegrationFixture.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,5 +510,40 @@ public async Task StatelessSessionAsync()
510510
Assert.That(statelessPerson2.Id, Is.EqualTo(personId));
511511
}
512512
}
513+
514+
[Test]
515+
public async Task QueryOverArithmeticAsync()
516+
{
517+
using (ISession s = OpenSession())
518+
using (ITransaction t = s.BeginTransaction())
519+
{
520+
await (s.SaveAsync(new Person() {Name = "test person 1", Age = 20}));
521+
await (s.SaveAsync(new Person() {Name = "test person 2", Age = 50}));
522+
await (t.CommitAsync());
523+
}
524+
525+
using (var s = OpenSession())
526+
{
527+
var persons1 = await (s.QueryOver<Person>().Where(p => ((p.Age * 2) / 2) + 20 - 20 == 20).ListAsync());
528+
var persons2 = await (s.QueryOver<Person>().Where(p => (-(-p.Age)) > 20).ListAsync());
529+
var persons3 = await (s.QueryOver<Person>().WhereRestrictionOn(p => ((p.Age * 2) / 2) + 20 - 20).IsBetween(19).And(21).ListAsync());
530+
var persons4 = await (s.QueryOver<Person>().WhereRestrictionOn(p => -(-p.Age)).IsBetween(19).And(21).ListAsync());
531+
var persons5 = await (s.QueryOver<Person>().WhereRestrictionOn(p => ((p.Age * 2) / 2) + 20 - 20).IsBetween(19).And(51).ListAsync());
532+
var persons6 = await (s.QueryOver<Person>().Where(p => ((p.Age * 2) / 2) + 20 - 20 == p.Age - p.Age + 20).ListAsync());
533+
#pragma warning disable CS0472 // The result of the expression is always the same since a value of this type is never equal to 'null'
534+
var persons7 = await (s.QueryOver<Person>().Where(p => ((p.Age * 2) / 2) + 20 - 20 == null || p.Age * 2 == 20 * 1).ListAsync());
535+
#pragma warning restore CS0472 // The result of the expression is always the same since a value of this type is never equal to 'null'
536+
var val1 = await (s.QueryOver<Person>().Select(p => p.Age * 2).Where(p => p.Age == 20).SingleOrDefaultAsync<int>());
537+
538+
Assert.That(persons1.Count, Is.EqualTo(1));
539+
Assert.That(persons2.Count, Is.EqualTo(1));
540+
Assert.That(persons3.Count, Is.EqualTo(1));
541+
Assert.That(persons4.Count, Is.EqualTo(1));
542+
Assert.That(persons5.Count, Is.EqualTo(2));
543+
Assert.That(persons6.Count, Is.EqualTo(1));
544+
Assert.That(persons7.Count, Is.EqualTo(0));
545+
Assert.That(val1, Is.EqualTo(40));
546+
}
547+
}
513548
}
514549
}

src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,5 +498,40 @@ public void StatelessSession()
498498
Assert.That(statelessPerson2.Id, Is.EqualTo(personId));
499499
}
500500
}
501+
502+
[Test]
503+
public void QueryOverArithmetic()
504+
{
505+
using (ISession s = OpenSession())
506+
using (ITransaction t = s.BeginTransaction())
507+
{
508+
s.Save(new Person() {Name = "test person 1", Age = 20});
509+
s.Save(new Person() {Name = "test person 2", Age = 50});
510+
t.Commit();
511+
}
512+
513+
using (var s = OpenSession())
514+
{
515+
var persons1 = s.QueryOver<Person>().Where(p => ((p.Age * 2) / 2) + 20 - 20 == 20).List();
516+
var persons2 = s.QueryOver<Person>().Where(p => (-(-p.Age)) > 20).List();
517+
var persons3 = s.QueryOver<Person>().WhereRestrictionOn(p => ((p.Age * 2) / 2) + 20 - 20).IsBetween(19).And(21).List();
518+
var persons4 = s.QueryOver<Person>().WhereRestrictionOn(p => -(-p.Age)).IsBetween(19).And(21).List();
519+
var persons5 = s.QueryOver<Person>().WhereRestrictionOn(p => ((p.Age * 2) / 2) + 20 - 20).IsBetween(19).And(51).List();
520+
var persons6 = s.QueryOver<Person>().Where(p => ((p.Age * 2) / 2) + 20 - 20 == p.Age - p.Age + 20).List();
521+
#pragma warning disable CS0472 // The result of the expression is always the same since a value of this type is never equal to 'null'
522+
var persons7 = s.QueryOver<Person>().Where(p => ((p.Age * 2) / 2) + 20 - 20 == null || p.Age * 2 == 20 * 1).List();
523+
#pragma warning restore CS0472 // The result of the expression is always the same since a value of this type is never equal to 'null'
524+
var val1 = s.QueryOver<Person>().Select(p => p.Age * 2).Where(p => p.Age == 20).SingleOrDefault<int>();
525+
526+
Assert.That(persons1.Count, Is.EqualTo(1));
527+
Assert.That(persons2.Count, Is.EqualTo(1));
528+
Assert.That(persons3.Count, Is.EqualTo(1));
529+
Assert.That(persons4.Count, Is.EqualTo(1));
530+
Assert.That(persons5.Count, Is.EqualTo(2));
531+
Assert.That(persons6.Count, Is.EqualTo(1));
532+
Assert.That(persons7.Count, Is.EqualTo(0));
533+
Assert.That(val1, Is.EqualTo(40));
534+
}
535+
}
501536
}
502537
}

src/NHibernate/Criterion/ConstantProjection.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace NHibernate.Criterion
1313
public class ConstantProjection : SimpleProjection
1414
{
1515
private readonly object value;
16-
private readonly TypedValue typedValue;
16+
public TypedValue TypedValue { get; }
1717

1818
public ConstantProjection(object value) : this(value, NHibernateUtil.GuessType(value.GetType()))
1919
{
@@ -22,7 +22,7 @@ public ConstantProjection(object value) : this(value, NHibernateUtil.GuessType(v
2222
public ConstantProjection(object value, IType type)
2323
{
2424
this.value = value;
25-
typedValue = new TypedValue(type, this.value);
25+
TypedValue = new TypedValue(type, this.value);
2626
}
2727

2828
public override bool IsAggregate
@@ -43,19 +43,19 @@ public override bool IsGrouped
4343
public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery)
4444
{
4545
return new SqlString(
46-
criteriaQuery.NewQueryParameter(typedValue).Single(),
46+
criteriaQuery.NewQueryParameter(TypedValue).Single(),
4747
" as ",
4848
GetColumnAliases(position, criteria, criteriaQuery)[0]);
4949
}
5050

5151
public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery)
5252
{
53-
return new IType[] { typedValue.Type };
53+
return new IType[] { TypedValue.Type };
5454
}
5555

5656
public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery)
5757
{
58-
return new TypedValue[] { typedValue };
58+
return new TypedValue[] { TypedValue };
5959
}
6060
}
6161
}

0 commit comments

Comments
 (0)