From 0a2869834437185d8805ada3871b17b9a0b2b6df Mon Sep 17 00:00:00 2001 From: Emil Tzvetkov Date: Mon, 27 Jul 2020 19:09:48 +0300 Subject: [PATCH 1/7] GH-2454 fix ConditionalProjection GetType from outer query --- .../NHSpecificTest/GH2454/FixtureByCode.cs | 116 ++++++++++++++++++ .../NHSpecificTest/GH2454/Domain.cs | 25 ++++ .../NHSpecificTest/GH2454/FixtureByCode.cs | 105 ++++++++++++++++ .../Criteria/CriteriaQueryTranslator.cs | 9 +- 4 files changed, 252 insertions(+), 3 deletions(-) create mode 100644 src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH2454/Domain.cs create mode 100644 src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs new file mode 100644 index 00000000000..2d30adfec12 --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs @@ -0,0 +1,116 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using NHibernate.Cfg.MappingSchema; +using NHibernate.Criterion; +using NHibernate.Mapping.ByCode; +using NHibernate.SqlCommand; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH2454 +{ + using System.Threading.Tasks; + [TestFixture] + public class ByCodeFixtureAsync : TestCaseMappingByCode + { + protected override HbmMapping GetMappings() + { + var mapper = new ModelMapper(); + + mapper.Class(rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.Name); + }); + + mapper.Class(rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.Name); + rc.ManyToOne(x => x.Project, m => { m.Column("ProjectId"); m.NotNullable(true); }); + }); + + mapper.Class(rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.Name); + rc.ManyToOne(x => x.Component1, m => { m.Column("Component1Id"); m.NotNullable(true); }); + rc.ManyToOne(x => x.Component2, m => { m.Column("Component2Id"); m.NotNullable(false); }); + }); + + return mapper.CompileMappingForAllExplicitlyAddedEntities(); + } + + [Test] + public async Task SubqueryCorrelatedThroughConditional() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + // data + { + // alpha entities + var projectAlpha = new Project { Name = "Alpha" }; + session.Save(projectAlpha); + + var componentAlpha = new Component { Project = projectAlpha, Name = "Thingie" }; + session.Save(componentAlpha); + + var tagAlpha = new Tag { Component1 = componentAlpha, Name = "A20" }; + session.Save(tagAlpha); + + // beta entities + var projectBeta = new Project { Name = "Beta" }; + session.Save(projectBeta); + + var componentBeta = new Component { Project = projectBeta, Name = "Thingie" }; + session.Save(componentBeta); + + var tagBeta = new Tag { Component1 = componentBeta, Name = "B17" }; + session.Save(tagBeta); + } + + session.Flush(); + + // query + { + ICriteria tagCriteria = session.CreateCriteria(typeof(Tag), "t"); + tagCriteria.CreateCriteria("Component1", "c1"); + tagCriteria.CreateCriteria("Component2", "c2", JoinType.LeftOuterJoin); + + IProjection projectNameProjection; + { + // create correlated subquery + var projectCriteria = DetachedCriteria.For(typeof(Project), "p"); + + var conditionalCorrelationProjection = Projections.Conditional( + Restrictions.IsNotNull(Projections.Property("t.Component2")), + Projections.Property("c2.Project"), + Projections.Property("c1.Project")); + projectCriteria.Add(Restrictions.EqProperty("p.Id", conditionalCorrelationProjection)); + + projectCriteria.SetProjection(Projections.Property("p.Name")); + + projectNameProjection = Projections.SubQuery(projectCriteria); + } + + tagCriteria.Add(Restrictions.Eq(projectNameProjection, "Beta")); + tagCriteria.SetProjection(Projections.Property("t.Name")); + + // run query + + var results = await (tagCriteria.ListAsync()); + + Assert.That(results, Is.EquivalentTo(new[] { "B17" })); + } + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH2454/Domain.cs b/src/NHibernate.Test/NHSpecificTest/GH2454/Domain.cs new file mode 100644 index 00000000000..48fe46e2b5c --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH2454/Domain.cs @@ -0,0 +1,25 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.GH2454 +{ + public class Project + { + public virtual Guid Id { get; set; } + public virtual string Name { get; set; } + } + + public class Component + { + public virtual Guid Id { get; set; } + public virtual string Name { get; set; } + public virtual Project Project { get; set; } + } + + public class Tag + { + public virtual Guid Id { get; set; } + public virtual string Name { get; set; } + public virtual Component Component1 { get; set; } + public virtual Component Component2 { get; set; } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs b/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs new file mode 100644 index 00000000000..f2376adfc30 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs @@ -0,0 +1,105 @@ +using NHibernate.Cfg.MappingSchema; +using NHibernate.Criterion; +using NHibernate.Mapping.ByCode; +using NHibernate.SqlCommand; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH2454 +{ + [TestFixture] + public class ByCodeFixture : TestCaseMappingByCode + { + protected override HbmMapping GetMappings() + { + var mapper = new ModelMapper(); + + mapper.Class(rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.Name); + }); + + mapper.Class(rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.Name); + rc.ManyToOne(x => x.Project, m => { m.Column("ProjectId"); m.NotNullable(true); }); + }); + + mapper.Class(rc => + { + rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb)); + rc.Property(x => x.Name); + rc.ManyToOne(x => x.Component1, m => { m.Column("Component1Id"); m.NotNullable(true); }); + rc.ManyToOne(x => x.Component2, m => { m.Column("Component2Id"); m.NotNullable(false); }); + }); + + return mapper.CompileMappingForAllExplicitlyAddedEntities(); + } + + [Test] + public void SubqueryCorrelatedThroughConditional() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + // data + { + // alpha entities + var projectAlpha = new Project { Name = "Alpha" }; + session.Save(projectAlpha); + + var componentAlpha = new Component { Project = projectAlpha, Name = "Thingie" }; + session.Save(componentAlpha); + + var tagAlpha = new Tag { Component1 = componentAlpha, Name = "A20" }; + session.Save(tagAlpha); + + // beta entities + var projectBeta = new Project { Name = "Beta" }; + session.Save(projectBeta); + + var componentBeta = new Component { Project = projectBeta, Name = "Thingie" }; + session.Save(componentBeta); + + var tagBeta = new Tag { Component1 = componentBeta, Name = "B17" }; + session.Save(tagBeta); + } + + session.Flush(); + + // query + { + ICriteria tagCriteria = session.CreateCriteria(typeof(Tag), "t"); + tagCriteria.CreateCriteria("Component1", "c1"); + tagCriteria.CreateCriteria("Component2", "c2", JoinType.LeftOuterJoin); + + IProjection projectNameProjection; + { + // create correlated subquery + var projectCriteria = DetachedCriteria.For(typeof(Project), "p"); + + var conditionalCorrelationProjection = Projections.Conditional( + Restrictions.IsNotNull(Projections.Property("t.Component2")), + Projections.Property("c2.Project"), + Projections.Property("c1.Project")); + projectCriteria.Add(Restrictions.EqProperty("p.Id", conditionalCorrelationProjection)); + + projectCriteria.SetProjection(Projections.Property("p.Name")); + + projectNameProjection = Projections.SubQuery(projectCriteria); + } + + tagCriteria.Add(Restrictions.Eq(projectNameProjection, "Beta")); + tagCriteria.SetProjection(Projections.Property("t.Name")); + + // run query + + var results = tagCriteria.List(); + + Assert.That(results, Is.EquivalentTo(new[] { "B17" })); + } + } + } + } +} diff --git a/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs b/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs index 5f315951413..65e9ec5611d 100644 --- a/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs +++ b/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs @@ -804,10 +804,13 @@ public IType GetTypeUsingProjection(ICriteria subcriteria, string propertyName) public IType GetType(ICriteria subcriteria, string propertyName) { - if(!TryParseCriteriaPath(subcriteria, propertyName, out var entityName, out var entityPropName, out _)) - throw new QueryException("Could not find property " + propertyName); + if (TryGetType(subcriteria, propertyName, out var resultType)) + return resultType; + + if (outerQueryTranslator != null) + return outerQueryTranslator.GetType(subcriteria, propertyName); - return GetPropertyMapping(entityName).ToType(entityPropName); + throw new QueryException("Could not find property " + propertyName); } public bool TryGetType(ICriteria subcriteria, string propertyName, out IType type) From c0e4118eff0f98afe7c578fb9a5e11fea2d603b8 Mon Sep 17 00:00:00 2001 From: Emil Tzvetkov Date: Tue, 28 Jul 2020 10:52:56 +0300 Subject: [PATCH 2/7] GH-2454 exclude test for dialects without SupportsScalarSubSelects (MsSqlCe) --- src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs b/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs index f2376adfc30..ca56576a189 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs @@ -9,6 +9,11 @@ namespace NHibernate.Test.NHSpecificTest.GH2454 [TestFixture] public class ByCodeFixture : TestCaseMappingByCode { + protected override bool AppliesTo(Dialect.Dialect dialect) + { + return dialect.SupportsScalarSubSelects; + } + protected override HbmMapping GetMappings() { var mapper = new ModelMapper(); From 7f8d3fecafd01dda10d13c8abca9c811d282115b Mon Sep 17 00:00:00 2001 From: Emil Tzvetkov Date: Tue, 28 Jul 2020 10:53:47 +0300 Subject: [PATCH 3/7] GH-2454 well generated asnyc test --- .../NHSpecificTest/GH2454/FixtureByCode.cs | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs index 2d30adfec12..efb3979e926 100644 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs @@ -20,6 +20,11 @@ namespace NHibernate.Test.NHSpecificTest.GH2454 [TestFixture] public class ByCodeFixtureAsync : TestCaseMappingByCode { + protected override bool AppliesTo(Dialect.Dialect dialect) + { + return dialect.SupportsScalarSubSelects; + } + protected override HbmMapping GetMappings() { var mapper = new ModelMapper(); @@ -49,7 +54,7 @@ protected override HbmMapping GetMappings() } [Test] - public async Task SubqueryCorrelatedThroughConditional() + public async Task SubqueryCorrelatedThroughConditionalAsync() { using (var session = OpenSession()) using (var transaction = session.BeginTransaction()) @@ -58,26 +63,26 @@ public async Task SubqueryCorrelatedThroughConditional() { // alpha entities var projectAlpha = new Project { Name = "Alpha" }; - session.Save(projectAlpha); + await (session.SaveAsync(projectAlpha)); var componentAlpha = new Component { Project = projectAlpha, Name = "Thingie" }; - session.Save(componentAlpha); + await (session.SaveAsync(componentAlpha)); var tagAlpha = new Tag { Component1 = componentAlpha, Name = "A20" }; - session.Save(tagAlpha); + await (session.SaveAsync(tagAlpha)); // beta entities var projectBeta = new Project { Name = "Beta" }; - session.Save(projectBeta); + await (session.SaveAsync(projectBeta)); var componentBeta = new Component { Project = projectBeta, Name = "Thingie" }; - session.Save(componentBeta); + await (session.SaveAsync(componentBeta)); var tagBeta = new Tag { Component1 = componentBeta, Name = "B17" }; - session.Save(tagBeta); + await (session.SaveAsync(tagBeta)); } - session.Flush(); + await (session.FlushAsync()); // query { From caa7bcbf1afba2dfe0f63fe09f849b9866101614 Mon Sep 17 00:00:00 2001 From: Roman Artiukhin Date: Wed, 9 Sep 2020 09:41:40 +0300 Subject: [PATCH 4/7] use GetType --- .../Loader/Criteria/CriteriaQueryTranslator.cs | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs b/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs index 65e9ec5611d..1e7bc8a59fd 100644 --- a/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs +++ b/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs @@ -778,18 +778,8 @@ public IType GetTypeUsingProjection(ICriteria subcriteria, string propertyName) if (projectionTypes == null) { - //it does not refer to an alias of a projection, - //look for a property - - if (TryGetType(subcriteria, propertyName, out var type)) - { - return type; - } - if (outerQueryTranslator != null) - { - return outerQueryTranslator.GetTypeUsingProjection(subcriteria, propertyName); - } - throw new QueryException("Could not find property " + propertyName); + //it does not refer to an alias of a projection, look for a property + return GetType(subcriteria, propertyName); } else { From 5f143fa51fc2d211a2514dec6e51aa976c558b1b Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Fri, 11 Sep 2020 10:05:24 +1200 Subject: [PATCH 5/7] Fix whitespaces --- src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs b/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs index 1e7bc8a59fd..955c4802dd3 100644 --- a/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs +++ b/src/NHibernate/Loader/Criteria/CriteriaQueryTranslator.cs @@ -778,8 +778,8 @@ public IType GetTypeUsingProjection(ICriteria subcriteria, string propertyName) if (projectionTypes == null) { - //it does not refer to an alias of a projection, look for a property - return GetType(subcriteria, propertyName); + //it does not refer to an alias of a projection, look for a property + return GetType(subcriteria, propertyName); } else { From 38612a0e963ee78e456cb6b19c4395eebbfc7cee Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Fri, 11 Sep 2020 10:15:12 +1200 Subject: [PATCH 6/7] Cleanup tests --- .../NHSpecificTest/GH2454/FixtureByCode.cs | 93 ++++++++++--------- .../NHSpecificTest/GH2454/FixtureByCode.cs | 93 ++++++++++--------- 2 files changed, 100 insertions(+), 86 deletions(-) diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs index efb3979e926..d13c3929e18 100644 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs @@ -53,68 +53,75 @@ protected override HbmMapping GetMappings() return mapper.CompileMappingForAllExplicitlyAddedEntities(); } - [Test] - public async Task SubqueryCorrelatedThroughConditionalAsync() + protected override void OnSetUp() { using (var session = OpenSession()) using (var transaction = session.BeginTransaction()) { - // data - { - // alpha entities - var projectAlpha = new Project { Name = "Alpha" }; - await (session.SaveAsync(projectAlpha)); + // alpha entities + var projectAlpha = new Project {Name = "Alpha"}; + session.Save(projectAlpha); - var componentAlpha = new Component { Project = projectAlpha, Name = "Thingie" }; - await (session.SaveAsync(componentAlpha)); + var componentAlpha = new Component {Project = projectAlpha, Name = "Thingie"}; + session.Save(componentAlpha); - var tagAlpha = new Tag { Component1 = componentAlpha, Name = "A20" }; - await (session.SaveAsync(tagAlpha)); + var tagAlpha = new Tag {Component1 = componentAlpha, Name = "A20"}; + session.Save(tagAlpha); - // beta entities - var projectBeta = new Project { Name = "Beta" }; - await (session.SaveAsync(projectBeta)); + // beta entities + var projectBeta = new Project {Name = "Beta"}; + session.Save(projectBeta); - var componentBeta = new Component { Project = projectBeta, Name = "Thingie" }; - await (session.SaveAsync(componentBeta)); + var componentBeta = new Component {Project = projectBeta, Name = "Thingie"}; + session.Save(componentBeta); - var tagBeta = new Tag { Component1 = componentBeta, Name = "B17" }; - await (session.SaveAsync(tagBeta)); - } + var tagBeta = new Tag {Component1 = componentBeta, Name = "B17"}; + session.Save(tagBeta); - await (session.FlushAsync()); + transaction.Commit(); + } + } - // query - { - ICriteria tagCriteria = session.CreateCriteria(typeof(Tag), "t"); - tagCriteria.CreateCriteria("Component1", "c1"); - tagCriteria.CreateCriteria("Component2", "c2", JoinType.LeftOuterJoin); + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + session.CreateQuery("delete from System.Object").ExecuteUpdate(); + transaction.Commit(); + } + } - IProjection projectNameProjection; - { - // create correlated subquery - var projectCriteria = DetachedCriteria.For(typeof(Project), "p"); + [Test] + public async Task SubqueryCorrelatedThroughConditionalAsync() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var tagCriteria = session.CreateCriteria(typeof(Tag), "t"); + tagCriteria.CreateCriteria("Component1", "c1"); + tagCriteria.CreateCriteria("Component2", "c2", JoinType.LeftOuterJoin); - var conditionalCorrelationProjection = Projections.Conditional( - Restrictions.IsNotNull(Projections.Property("t.Component2")), - Projections.Property("c2.Project"), - Projections.Property("c1.Project")); - projectCriteria.Add(Restrictions.EqProperty("p.Id", conditionalCorrelationProjection)); + // create correlated subquery + var projectCriteria = DetachedCriteria.For(typeof(Project), "p"); - projectCriteria.SetProjection(Projections.Property("p.Name")); + var conditionalCorrelationProjection = Projections.Conditional( + Restrictions.IsNotNull(Projections.Property("t.Component2")), + Projections.Property("c2.Project"), + Projections.Property("c1.Project")); + projectCriteria.Add(Restrictions.EqProperty("p.Id", conditionalCorrelationProjection)); - projectNameProjection = Projections.SubQuery(projectCriteria); - } + projectCriteria.SetProjection(Projections.Property("p.Name")); - tagCriteria.Add(Restrictions.Eq(projectNameProjection, "Beta")); - tagCriteria.SetProjection(Projections.Property("t.Name")); + var projectNameProjection = Projections.SubQuery(projectCriteria); - // run query + tagCriteria.Add(Restrictions.Eq(projectNameProjection, "Beta")); + tagCriteria.SetProjection(Projections.Property("t.Name")); - var results = await (tagCriteria.ListAsync()); + // run query + var results = await (tagCriteria.ListAsync()); - Assert.That(results, Is.EquivalentTo(new[] { "B17" })); - } + Assert.That(results, Is.EquivalentTo(new[] {"B17"})); } } } diff --git a/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs b/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs index ca56576a189..b3a6bb750c4 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs @@ -42,68 +42,75 @@ protected override HbmMapping GetMappings() return mapper.CompileMappingForAllExplicitlyAddedEntities(); } - [Test] - public void SubqueryCorrelatedThroughConditional() + protected override void OnSetUp() { using (var session = OpenSession()) using (var transaction = session.BeginTransaction()) { - // data - { - // alpha entities - var projectAlpha = new Project { Name = "Alpha" }; - session.Save(projectAlpha); + // alpha entities + var projectAlpha = new Project {Name = "Alpha"}; + session.Save(projectAlpha); - var componentAlpha = new Component { Project = projectAlpha, Name = "Thingie" }; - session.Save(componentAlpha); + var componentAlpha = new Component {Project = projectAlpha, Name = "Thingie"}; + session.Save(componentAlpha); - var tagAlpha = new Tag { Component1 = componentAlpha, Name = "A20" }; - session.Save(tagAlpha); + var tagAlpha = new Tag {Component1 = componentAlpha, Name = "A20"}; + session.Save(tagAlpha); - // beta entities - var projectBeta = new Project { Name = "Beta" }; - session.Save(projectBeta); + // beta entities + var projectBeta = new Project {Name = "Beta"}; + session.Save(projectBeta); - var componentBeta = new Component { Project = projectBeta, Name = "Thingie" }; - session.Save(componentBeta); + var componentBeta = new Component {Project = projectBeta, Name = "Thingie"}; + session.Save(componentBeta); - var tagBeta = new Tag { Component1 = componentBeta, Name = "B17" }; - session.Save(tagBeta); - } + var tagBeta = new Tag {Component1 = componentBeta, Name = "B17"}; + session.Save(tagBeta); - session.Flush(); + transaction.Commit(); + } + } - // query - { - ICriteria tagCriteria = session.CreateCriteria(typeof(Tag), "t"); - tagCriteria.CreateCriteria("Component1", "c1"); - tagCriteria.CreateCriteria("Component2", "c2", JoinType.LeftOuterJoin); + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var transaction = session.BeginTransaction()) + { + session.CreateQuery("delete from System.Object").ExecuteUpdate(); + transaction.Commit(); + } + } - IProjection projectNameProjection; - { - // create correlated subquery - var projectCriteria = DetachedCriteria.For(typeof(Project), "p"); + [Test] + public void SubqueryCorrelatedThroughConditional() + { + using (var session = OpenSession()) + using (session.BeginTransaction()) + { + var tagCriteria = session.CreateCriteria(typeof(Tag), "t"); + tagCriteria.CreateCriteria("Component1", "c1"); + tagCriteria.CreateCriteria("Component2", "c2", JoinType.LeftOuterJoin); - var conditionalCorrelationProjection = Projections.Conditional( - Restrictions.IsNotNull(Projections.Property("t.Component2")), - Projections.Property("c2.Project"), - Projections.Property("c1.Project")); - projectCriteria.Add(Restrictions.EqProperty("p.Id", conditionalCorrelationProjection)); + // create correlated subquery + var projectCriteria = DetachedCriteria.For(typeof(Project), "p"); - projectCriteria.SetProjection(Projections.Property("p.Name")); + var conditionalCorrelationProjection = Projections.Conditional( + Restrictions.IsNotNull(Projections.Property("t.Component2")), + Projections.Property("c2.Project"), + Projections.Property("c1.Project")); + projectCriteria.Add(Restrictions.EqProperty("p.Id", conditionalCorrelationProjection)); - projectNameProjection = Projections.SubQuery(projectCriteria); - } + projectCriteria.SetProjection(Projections.Property("p.Name")); - tagCriteria.Add(Restrictions.Eq(projectNameProjection, "Beta")); - tagCriteria.SetProjection(Projections.Property("t.Name")); + var projectNameProjection = Projections.SubQuery(projectCriteria); - // run query + tagCriteria.Add(Restrictions.Eq(projectNameProjection, "Beta")); + tagCriteria.SetProjection(Projections.Property("t.Name")); - var results = tagCriteria.List(); + // run query + var results = tagCriteria.List(); - Assert.That(results, Is.EquivalentTo(new[] { "B17" })); - } + Assert.That(results, Is.EquivalentTo(new[] {"B17"})); } } } From 8aa3e84b1c210dc80a1ef001846c96e318c90f65 Mon Sep 17 00:00:00 2001 From: Alex Zaytsev Date: Fri, 11 Sep 2020 12:45:51 +1200 Subject: [PATCH 7/7] Fix test tear-down --- .../Async/NHSpecificTest/GH2454/FixtureByCode.cs | 4 +++- src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs index d13c3929e18..11e91807118 100644 --- a/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2454/FixtureByCode.cs @@ -87,7 +87,9 @@ protected override void OnTearDown() using (var session = OpenSession()) using (var transaction = session.BeginTransaction()) { - session.CreateQuery("delete from System.Object").ExecuteUpdate(); + session.CreateQuery("delete from Tag").ExecuteUpdate(); + session.CreateQuery("delete from Component").ExecuteUpdate(); + session.CreateQuery("delete from Project").ExecuteUpdate(); transaction.Commit(); } } diff --git a/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs b/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs index b3a6bb750c4..30a93637682 100644 --- a/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs +++ b/src/NHibernate.Test/NHSpecificTest/GH2454/FixtureByCode.cs @@ -76,7 +76,9 @@ protected override void OnTearDown() using (var session = OpenSession()) using (var transaction = session.BeginTransaction()) { - session.CreateQuery("delete from System.Object").ExecuteUpdate(); + session.CreateQuery("delete from Tag").ExecuteUpdate(); + session.CreateQuery("delete from Component").ExecuteUpdate(); + session.CreateQuery("delete from Project").ExecuteUpdate(); transaction.Commit(); } }