From 40fdb4e46f0e4d069da17e02d152fa7f4a95a4ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= Date: Wed, 22 Feb 2017 00:23:06 +0100 Subject: [PATCH 1/2] Test cases for NH-3950. --- .../NHSpecificTest/NH3950/Entity.cs | 10 ++ .../NHSpecificTest/NH3950/Fixture.cs | 96 +++++++++++++++++++ .../NHSpecificTest/NH3950/Mappings.hbm.xml | 9 ++ src/NHibernate.Test/NHibernate.Test.csproj | 3 + 4 files changed, 118 insertions(+) create mode 100644 src/NHibernate.Test/NHSpecificTest/NH3950/Entity.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/NH3950/Fixture.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/NH3950/Mappings.hbm.xml diff --git a/src/NHibernate.Test/NHSpecificTest/NH3950/Entity.cs b/src/NHibernate.Test/NHSpecificTest/NH3950/Entity.cs new file mode 100644 index 00000000000..c2a183ba928 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3950/Entity.cs @@ -0,0 +1,10 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.NH3950 +{ + class Entity + { + public virtual Guid Id { get; set; } + public virtual string Name { get; set; } + } +} \ No newline at end of file diff --git a/src/NHibernate.Test/NHSpecificTest/NH3950/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/NH3950/Fixture.cs new file mode 100644 index 00000000000..5b405f714ee --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3950/Fixture.cs @@ -0,0 +1,96 @@ +using System.Linq; +using NHibernate.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH3950 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnSetUp() + { + using (ISession session = OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + var e1 = new Entity {Name = "Bob"}; + session.Save(e1); + + var e2 = new Entity {Name = "Sally"}; + session.Save(e2); + + session.Flush(); + transaction.Commit(); + } + } + + protected override void OnTearDown() + { + using (ISession session = OpenSession()) + using (ITransaction transaction = session.BeginTransaction()) + { + session.Delete("from System.Object"); + + session.Flush(); + transaction.Commit(); + } + } + + [Test] + public void FirstFutureValue() + { + using (ISession session = OpenSession()) + using (session.BeginTransaction()) + { + var result = session.Query() + .OrderBy(e => e.Name) + .ToFutureValue(q => q.First()); + + Assert.AreEqual("Bob", result.Value.Name); + } + } + + [Test] + public void FirstOrDefaultFutureValue() + { + using (ISession session = OpenSession()) + using (session.BeginTransaction()) + { + var result = session.Query() + .Select(e => e.Name) + .OrderBy(n => n) + .ToFutureValue(q => q.FirstOrDefault()); + + Assert.AreEqual("Bob", result.Value); + } + } + + [Test] + public void SingleFutureValue() + { + using (ISession session = OpenSession()) + using (session.BeginTransaction()) + { + var result = session.Query() + .Where(e => e.Name == "Bob") + .ToFutureValue(q => q.Single()); + + Assert.AreEqual("Bob", result.Value.Name); + } + } + + [Test] + public void SingleOrDefaultFutureValue() + { + using (ISession session = OpenSession()) + using (session.BeginTransaction()) + { + var result = session.Query() + .Select(e => e.Name) + .Where(n => n == "Bob") + .ToFutureValue(q => q.SingleOrDefault()); + + Assert.AreEqual("Bob", result.Value); + } + } + } +} \ No newline at end of file diff --git a/src/NHibernate.Test/NHSpecificTest/NH3950/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/NH3950/Mappings.hbm.xml new file mode 100644 index 00000000000..a98e9c53900 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3950/Mappings.hbm.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/src/NHibernate.Test/NHibernate.Test.csproj b/src/NHibernate.Test/NHibernate.Test.csproj index f21597364cf..e3c3164f24e 100644 --- a/src/NHibernate.Test/NHibernate.Test.csproj +++ b/src/NHibernate.Test/NHibernate.Test.csproj @@ -736,6 +736,8 @@ + + @@ -3201,6 +3203,7 @@ + From 96048a121170bc3aa5b9a82a4ada1cb276b2cc09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Delaporte?= Date: Wed, 22 Feb 2017 00:29:53 +0100 Subject: [PATCH 2/2] NH-3950 fix. --- src/NHibernate/Impl/FutureValue.cs | 71 ++++++++++++++---------------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/src/NHibernate/Impl/FutureValue.cs b/src/NHibernate/Impl/FutureValue.cs index 7866eeab5d1..04a6fa6d72a 100644 --- a/src/NHibernate/Impl/FutureValue.cs +++ b/src/NHibernate/Impl/FutureValue.cs @@ -1,47 +1,44 @@ using System; using System.Collections; using System.Collections.Generic; +using System.Linq; namespace NHibernate.Impl { - internal class FutureValue : IFutureValue, IDelayedValue - { - public delegate IEnumerable GetResult(); - - private readonly GetResult getResult; - - public FutureValue(GetResult result) - { - getResult = result; - } - - public T Value - { - get - { - var result = getResult(); + internal class FutureValue : IFutureValue, IDelayedValue + { + public delegate IEnumerable GetResult(); + + private readonly GetResult getResult; + + public FutureValue(GetResult result) + { + getResult = result; + } + + public T Value + { + get + { + var result = getResult(); + if (ExecuteOnEval != null) + // When not null, ExecuteOnEval is fetched with PostExecuteTransformer from IntermediateHqlTree + // through ExpressionToHqlTranslationResults, which requires a IQueryable as input and directly + // yields the scalar result when the query is scalar. + return (T)ExecuteOnEval.DynamicInvoke(result.AsQueryable()); + var enumerator = result.GetEnumerator(); if (!enumerator.MoveNext()) - { - var defVal = default(T); - if (ExecuteOnEval != null) - defVal = (T)ExecuteOnEval.DynamicInvoke(defVal); - return defVal; - } - - var val = enumerator.Current; - - if (ExecuteOnEval != null) - val = (T)ExecuteOnEval.DynamicInvoke(val); - - return val; - } - } - - public Delegate ExecuteOnEval - { - get; set; - } - } + return default(T); + + return enumerator.Current; + } + } + + public Delegate ExecuteOnEval + { + get; set; + } + } } \ No newline at end of file