diff --git a/src/NHibernate.Test/Async/NHSpecificTest/NH3506/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/NH3506/Fixture.cs new file mode 100644 index 00000000000..3ee9ae36268 --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/NH3506/Fixture.cs @@ -0,0 +1,120 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by AsyncGenerator. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + + +using System; +using System.Collections.Generic; +using System.Linq; +using NHibernate.SqlCommand; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH3506 +{ + using System.Threading.Tasks; + [TestFixture] + public class FixtureAsync : BugTestCase + { + private Department _department; + + private Employee _employee1; + + private Employee _employee2; + + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + _department = new Department(); + + _employee1 = new Employee + { + Department = _department + }; + + _employee2 = new Employee(); + + session.Save(_department); + session.Save(_employee1); + session.Save(_employee2); + + tx.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + session.Delete(_department); + session.Delete(_employee1); + session.Delete(_employee2); + + tx.Commit(); + } + } + + [Theory] + public async Task Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_HQLAsync(bool enableFilter) + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + if (enableFilter) + session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow); + + var employees = await (session.CreateQuery("select e from Employee e left join e.Department d") + .ListAsync()); + + Assert.That(employees.Count, Is.EqualTo(2)); + + await (tx.CommitAsync()); + } + } + + [Theory] + public async Task Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_ICriteriaAsync(bool enableFilter) + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + if (enableFilter) + session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow); + + var employees = await (session.CreateCriteria() + .CreateCriteria("Department", JoinType.LeftOuterJoin) + .ListAsync()); + + Assert.That(employees.Count, Is.EqualTo(2)); + + await (tx.CommitAsync()); + } + } + + [Theory] + public async Task Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_QueryOverAsync(bool enableFilter) + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + if (enableFilter) + session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow); + + var employees = await (session.QueryOver() + .JoinQueryOver(x => x.Department, JoinType.LeftOuterJoin) + .ListAsync()); + + Assert.That(employees.Count, Is.EqualTo(2)); + + await (tx.CommitAsync()); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/NH3506/BaseClass.cs b/src/NHibernate.Test/NHSpecificTest/NH3506/BaseClass.cs new file mode 100644 index 00000000000..1e28c529c42 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3506/BaseClass.cs @@ -0,0 +1,9 @@ +using System; + +namespace NHibernate.Test.NHSpecificTest.NH3506 +{ + public class BaseClass + { + public virtual Guid Id { get; set; } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/NH3506/Department.cs b/src/NHibernate.Test/NHSpecificTest/NH3506/Department.cs new file mode 100644 index 00000000000..f3d3a833a4c --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3506/Department.cs @@ -0,0 +1,6 @@ +namespace NHibernate.Test.NHSpecificTest.NH3506 +{ + public class Department : BaseClass + { + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/NH3506/Employee.cs b/src/NHibernate.Test/NHSpecificTest/NH3506/Employee.cs new file mode 100644 index 00000000000..7e15c859882 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3506/Employee.cs @@ -0,0 +1,7 @@ +namespace NHibernate.Test.NHSpecificTest.NH3506 +{ + public class Employee : BaseClass + { + public virtual Department Department { get; set; } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/NH3506/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/NH3506/Fixture.cs new file mode 100644 index 00000000000..ffc6a821136 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3506/Fixture.cs @@ -0,0 +1,109 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NHibernate.SqlCommand; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.NH3506 +{ + [TestFixture] + public class Fixture : BugTestCase + { + private Department _department; + + private Employee _employee1; + + private Employee _employee2; + + protected override void OnSetUp() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + _department = new Department(); + + _employee1 = new Employee + { + Department = _department + }; + + _employee2 = new Employee(); + + session.Save(_department); + session.Save(_employee1); + session.Save(_employee2); + + tx.Commit(); + } + } + + protected override void OnTearDown() + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + session.Delete(_department); + session.Delete(_employee1); + session.Delete(_employee2); + + tx.Commit(); + } + } + + [Theory] + public void Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_HQL(bool enableFilter) + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + if (enableFilter) + session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow); + + var employees = session.CreateQuery("select e from Employee e left join e.Department d") + .List(); + + Assert.That(employees.Count, Is.EqualTo(2)); + + tx.Commit(); + } + } + + [Theory] + public void Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_ICriteria(bool enableFilter) + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + if (enableFilter) + session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow); + + var employees = session.CreateCriteria() + .CreateCriteria("Department", JoinType.LeftOuterJoin) + .List(); + + Assert.That(employees.Count, Is.EqualTo(2)); + + tx.Commit(); + } + } + + [Theory] + public void Querying_Employees_LeftJoining_On_Departments_Should_Return_All_Employees_QueryOver(bool enableFilter) + { + using (var session = OpenSession()) + using (var tx = session.BeginTransaction()) + { + if (enableFilter) + session.EnableFilter("ValidAtFilter").SetParameter("CurrentDate", DateTime.UtcNow); + + var employees = session.QueryOver() + .JoinQueryOver(x => x.Department, JoinType.LeftOuterJoin) + .List(); + + Assert.That(employees.Count, Is.EqualTo(2)); + + tx.Commit(); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/NH3506/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/NH3506/Mappings.hbm.xml new file mode 100644 index 00000000000..1d686b9d3a4 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/NH3506/Mappings.hbm.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/NHibernate/Loader/JoinWalker.cs b/src/NHibernate/Loader/JoinWalker.cs index fe3ea666811..372ef8bed73 100644 --- a/src/NHibernate/Loader/JoinWalker.cs +++ b/src/NHibernate/Loader/JoinWalker.cs @@ -687,7 +687,9 @@ protected JoinFragment MergeOuterJoins(IList associati outerjoin.ToFromFragmentString.IndexOfCaseInsensitive(manyToOneFilterFragment) == -1; if (joinClauseDoesNotContainsFilterAlready) { - outerjoin.AddCondition(manyToOneFilterFragment); + // Ensure that the join condition is added to the join, not the where clause. + // Adding the condition to the where clause causes left joins to become inner joins. + outerjoin.AddFromFragmentString(new SqlString(manyToOneFilterFragment)); } } }