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;
- }
- }
-}