diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2549/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2549/Fixture.cs new file mode 100644 index 00000000000..82227867203 --- /dev/null +++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2549/Fixture.cs @@ -0,0 +1,82 @@ +//------------------------------------------------------------------------------ +// +// 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.Linq; +using NUnit.Framework; +using NHibernate.Linq; + +namespace NHibernate.Test.NHSpecificTest.GH2549 +{ + using System.Threading.Tasks; + [TestFixture] + public class FixtureAsync : BugTestCase + { + protected override void OnSetUp() + { + using (var s = OpenSession()) + using (var t = s.BeginTransaction()) + { + s.Save(new Person {Id = 1, Name = "Name"}); + s.Save(new Customer {Deleted = false, Name = "Name", Id = 1}); + s.Save(new Customer {Deleted = true, Name = "Name", Id = 2}); + + t.Commit(); + } + } + + protected override void OnTearDown() + { + using (var s = OpenSession()) + using (var t = s.BeginTransaction()) + { + s.CreateQuery("delete from System.Object").ExecuteUpdate(); + t.Commit(); + } + } + + [Test] + public async Task EntityJoinFilterLinqAsync() + { + using (var s = OpenSession()) + { + var list = await ((from p in s.Query() + join c in s.Query() on p.Name equals c.Name + select p).ToListAsync()); + + s.EnableFilter("DeletedCustomer").SetParameter("deleted", false); + + var filteredList = await ((from p in s.Query() + join c in s.Query() on p.Name equals c.Name + select p).ToListAsync()); + + Assert.That(list, Has.Count.EqualTo(2)); + Assert.That(filteredList, Has.Count.EqualTo(1)); + } + } + + [Test] + public async Task EntityJoinFilterQueryOverAsync() + { + using (var s = OpenSession()) + { + Customer c = null; + Person p = null; + var list = await (s.QueryOver(() => p).JoinEntityAlias(() => c, () => c.Name == p.Name).ListAsync()); + + s.EnableFilter("DeletedCustomer").SetParameter("deleted", false); + + var filteredList = await (s.QueryOver(() => p).JoinEntityAlias(() => c, () => c.Name == p.Name).ListAsync()); + + Assert.That(list, Has.Count.EqualTo(2)); + Assert.That(filteredList, Has.Count.EqualTo(1)); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH2549/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH2549/Fixture.cs new file mode 100644 index 00000000000..a01c1ec2572 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH2549/Fixture.cs @@ -0,0 +1,70 @@ +using System.Linq; +using NUnit.Framework; + +namespace NHibernate.Test.NHSpecificTest.GH2549 +{ + [TestFixture] + public class Fixture : BugTestCase + { + protected override void OnSetUp() + { + using (var s = OpenSession()) + using (var t = s.BeginTransaction()) + { + s.Save(new Person {Id = 1, Name = "Name"}); + s.Save(new Customer {Deleted = false, Name = "Name", Id = 1}); + s.Save(new Customer {Deleted = true, Name = "Name", Id = 2}); + + t.Commit(); + } + } + + protected override void OnTearDown() + { + using (var s = OpenSession()) + using (var t = s.BeginTransaction()) + { + s.CreateQuery("delete from System.Object").ExecuteUpdate(); + t.Commit(); + } + } + + [Test] + public void EntityJoinFilterLinq() + { + using (var s = OpenSession()) + { + var list = (from p in s.Query() + join c in s.Query() on p.Name equals c.Name + select p).ToList(); + + s.EnableFilter("DeletedCustomer").SetParameter("deleted", false); + + var filteredList = (from p in s.Query() + join c in s.Query() on p.Name equals c.Name + select p).ToList(); + + Assert.That(list, Has.Count.EqualTo(2)); + Assert.That(filteredList, Has.Count.EqualTo(1)); + } + } + + [Test] + public void EntityJoinFilterQueryOver() + { + using (var s = OpenSession()) + { + Customer c = null; + Person p = null; + var list = s.QueryOver(() => p).JoinEntityAlias(() => c, () => c.Name == p.Name).List(); + + s.EnableFilter("DeletedCustomer").SetParameter("deleted", false); + + var filteredList = s.QueryOver(() => p).JoinEntityAlias(() => c, () => c.Name == p.Name).List(); + + Assert.That(list, Has.Count.EqualTo(2)); + Assert.That(filteredList, Has.Count.EqualTo(1)); + } + } + } +} diff --git a/src/NHibernate.Test/NHSpecificTest/GH2549/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH2549/Mappings.hbm.xml new file mode 100644 index 00000000000..65b540b9202 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH2549/Mappings.hbm.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/NHibernate.Test/NHSpecificTest/GH2549/Model.cs b/src/NHibernate.Test/NHSpecificTest/GH2549/Model.cs new file mode 100644 index 00000000000..b6d678c7b20 --- /dev/null +++ b/src/NHibernate.Test/NHSpecificTest/GH2549/Model.cs @@ -0,0 +1,15 @@ +namespace NHibernate.Test.NHSpecificTest.GH2549 +{ + public class Customer + { + public virtual int Id { get; set; } + public virtual bool Deleted { get; set; } + public virtual string Name { get; set; } + } + + public class Person + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + } +} diff --git a/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinFromElement.cs b/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinFromElement.cs index e2f4ce33365..4458d5cecce 100644 --- a/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinFromElement.cs +++ b/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinFromElement.cs @@ -1,4 +1,6 @@ -using Antlr.Runtime; +using System; +using Antlr.Runtime; +using NHibernate.Engine; using NHibernate.Persister.Entity; using NHibernate.SqlCommand; using NHibernate.Type; @@ -15,12 +17,9 @@ public EntityJoinFromElement(FromClause fromClause, IQueryable entityPersister, EntityType entityType = (EntityType) entityPersister.Type; InitializeEntity(fromClause, entityPersister.EntityName, entityPersister, entityType, alias, tableAlias); - JoinSequence = new EntityJoinJoinSequenceImpl( - SessionFactoryHelper.Factory, - entityType, - entityPersister.TableName, - tableAlias, - joinType); + //NH Specific: hibernate uses special class EntityJoinJoinSequenceImpl + JoinSequence = new JoinSequence(SessionFactoryHelper.Factory) + .AddJoin(entityType, tableAlias, joinType, Array.Empty()); fromClause.Walker.AddQuerySpaces(entityPersister.QuerySpaces); } diff --git a/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinJoinSequenceImpl.cs b/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinJoinSequenceImpl.cs deleted file mode 100644 index 430515223d0..00000000000 --- a/src/NHibernate/Hql/Ast/ANTLR/Tree/EntityJoinJoinSequenceImpl.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Collections.Generic; -using NHibernate.Engine; -using NHibernate.SqlCommand; -using NHibernate.Type; - -namespace NHibernate.Hql.Ast.ANTLR.Tree -{ - class EntityJoinJoinSequenceImpl : JoinSequence - { - private readonly EntityType _entityType; - private readonly string _tableName; - private readonly string _tableAlias; - private readonly JoinType _joinType; - - public EntityJoinJoinSequenceImpl(ISessionFactoryImplementor factory, EntityType entityType, string tableName, string tableAlias, JoinType joinType):base(factory) - { - _entityType = entityType; - _tableName = tableName; - _tableAlias = tableAlias; - _joinType = joinType; - } - - internal override JoinFragment ToJoinFragment( - IDictionary enabledFilters, - bool includeExtraJoins, - SqlString withClauseFragment, - string withClauseJoinAlias, - string withRootAlias) - { - var joinFragment = new ANSIJoinFragment(); - - var on = withClauseFragment ?? SqlString.Empty; - //Note: filters logic commented due to following issues - //1) Original code is non functional as SqlString is immutable and so all Append results are lost. Correct code would look like: on = on.Append(filters); - //2) Also it seems GetOnCondition always returns empty string for entity join (as IsReferenceToPrimaryKey is always true). - // So if filters for entity join really make sense we need to inline GetOnCondition part that retrieves filters -// var filters = _entityType.GetOnCondition(_tableAlias, Factory, enabledFilters); -// if (!string.IsNullOrEmpty(filters)) -// { -// on.Append(" and ").Append(filters); -// } - joinFragment.AddJoin(_tableName, _tableAlias, Array.Empty(), Array.Empty(), _joinType, on); - if (includeExtraJoins) - { - AddExtraJoins(joinFragment, _tableAlias, _entityType.GetAssociatedJoinable(Factory), _joinType == JoinType.InnerJoin); - } - return joinFragment; - } - } -}