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 c9aa966b5bb..8fae8736b23 100644 --- a/src/NHibernate.Test/NHibernate.Test.csproj +++ b/src/NHibernate.Test/NHibernate.Test.csproj @@ -737,6 +737,8 @@ + + @@ -3206,6 +3208,7 @@ + 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