Skip to content

Support basic arithmetic operations (+, -, *, /) in QueryOver #2156

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions src/NHibernate.Test/Async/Criteria/Lambda/IntegrationFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -510,5 +510,40 @@ public async Task StatelessSessionAsync()
Assert.That(statelessPerson2.Id, Is.EqualTo(personId));
}
}

[Test]
public async Task QueryOverArithmeticAsync()
{
using (ISession s = OpenSession())
using (ITransaction t = s.BeginTransaction())
{
await (s.SaveAsync(new Person() {Name = "test person 1", Age = 20}));
await (s.SaveAsync(new Person() {Name = "test person 2", Age = 50}));
await (t.CommitAsync());
}

using (var s = OpenSession())
{
var persons1 = await (s.QueryOver<Person>().Where(p => ((p.Age * 2) / 2) + 20 - 20 == 20).ListAsync());
var persons2 = await (s.QueryOver<Person>().Where(p => (-(-p.Age)) > 20).ListAsync());
var persons3 = await (s.QueryOver<Person>().WhereRestrictionOn(p => ((p.Age * 2) / 2) + 20 - 20).IsBetween(19).And(21).ListAsync());
var persons4 = await (s.QueryOver<Person>().WhereRestrictionOn(p => -(-p.Age)).IsBetween(19).And(21).ListAsync());
var persons5 = await (s.QueryOver<Person>().WhereRestrictionOn(p => ((p.Age * 2) / 2) + 20 - 20).IsBetween(19).And(51).ListAsync());
var persons6 = await (s.QueryOver<Person>().Where(p => ((p.Age * 2) / 2) + 20 - 20 == p.Age - p.Age + 20).ListAsync());
#pragma warning disable CS0472 // The result of the expression is always the same since a value of this type is never equal to 'null'
var persons7 = await (s.QueryOver<Person>().Where(p => ((p.Age * 2) / 2) + 20 - 20 == null || p.Age * 2 == 20 * 1).ListAsync());
#pragma warning restore CS0472 // The result of the expression is always the same since a value of this type is never equal to 'null'
var val1 = await (s.QueryOver<Person>().Select(p => p.Age * 2).Where(p => p.Age == 20).SingleOrDefaultAsync<int>());

Assert.That(persons1.Count, Is.EqualTo(1));
Assert.That(persons2.Count, Is.EqualTo(1));
Assert.That(persons3.Count, Is.EqualTo(1));
Assert.That(persons4.Count, Is.EqualTo(1));
Assert.That(persons5.Count, Is.EqualTo(2));
Assert.That(persons6.Count, Is.EqualTo(1));
Assert.That(persons7.Count, Is.EqualTo(0));
Assert.That(val1, Is.EqualTo(40));
}
}
}
}
35 changes: 35 additions & 0 deletions src/NHibernate.Test/Criteria/Lambda/IntegrationFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -498,5 +498,40 @@ public void StatelessSession()
Assert.That(statelessPerson2.Id, Is.EqualTo(personId));
}
}

[Test]
public void QueryOverArithmetic()
{
using (ISession s = OpenSession())
using (ITransaction t = s.BeginTransaction())
{
s.Save(new Person() {Name = "test person 1", Age = 20});
s.Save(new Person() {Name = "test person 2", Age = 50});
t.Commit();
}

using (var s = OpenSession())
{
var persons1 = s.QueryOver<Person>().Where(p => ((p.Age * 2) / 2) + 20 - 20 == 20).List();
var persons2 = s.QueryOver<Person>().Where(p => (-(-p.Age)) > 20).List();
var persons3 = s.QueryOver<Person>().WhereRestrictionOn(p => ((p.Age * 2) / 2) + 20 - 20).IsBetween(19).And(21).List();
var persons4 = s.QueryOver<Person>().WhereRestrictionOn(p => -(-p.Age)).IsBetween(19).And(21).List();
var persons5 = s.QueryOver<Person>().WhereRestrictionOn(p => ((p.Age * 2) / 2) + 20 - 20).IsBetween(19).And(51).List();
var persons6 = s.QueryOver<Person>().Where(p => ((p.Age * 2) / 2) + 20 - 20 == p.Age - p.Age + 20).List();
#pragma warning disable CS0472 // The result of the expression is always the same since a value of this type is never equal to 'null'
var persons7 = s.QueryOver<Person>().Where(p => ((p.Age * 2) / 2) + 20 - 20 == null || p.Age * 2 == 20 * 1).List();
#pragma warning restore CS0472 // The result of the expression is always the same since a value of this type is never equal to 'null'
var val1 = s.QueryOver<Person>().Select(p => p.Age * 2).Where(p => p.Age == 20).SingleOrDefault<int>();

Assert.That(persons1.Count, Is.EqualTo(1));
Assert.That(persons2.Count, Is.EqualTo(1));
Assert.That(persons3.Count, Is.EqualTo(1));
Assert.That(persons4.Count, Is.EqualTo(1));
Assert.That(persons5.Count, Is.EqualTo(2));
Assert.That(persons6.Count, Is.EqualTo(1));
Assert.That(persons7.Count, Is.EqualTo(0));
Assert.That(val1, Is.EqualTo(40));
}
}
}
}
10 changes: 5 additions & 5 deletions src/NHibernate/Criterion/ConstantProjection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ namespace NHibernate.Criterion
public class ConstantProjection : SimpleProjection
{
private readonly object value;
private readonly TypedValue typedValue;
public TypedValue TypedValue { get; }

public ConstantProjection(object value) : this(value, NHibernateUtil.GuessType(value.GetType()))
{
Expand All @@ -22,7 +22,7 @@ public ConstantProjection(object value) : this(value, NHibernateUtil.GuessType(v
public ConstantProjection(object value, IType type)
{
this.value = value;
typedValue = new TypedValue(type, this.value);
TypedValue = new TypedValue(type, this.value);
}

public override bool IsAggregate
Expand All @@ -43,19 +43,19 @@ public override bool IsGrouped
public override SqlString ToSqlString(ICriteria criteria, int position, ICriteriaQuery criteriaQuery)
{
return new SqlString(
criteriaQuery.NewQueryParameter(typedValue).Single(),
criteriaQuery.NewQueryParameter(TypedValue).Single(),
" as ",
GetColumnAliases(position, criteria, criteriaQuery)[0]);
}

public override IType[] GetTypes(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
return new IType[] { typedValue.Type };
return new IType[] { TypedValue.Type };
}

public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
return new TypedValue[] { typedValue };
return new TypedValue[] { TypedValue };
}
}
}
Loading