diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2626/Fixture.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2626/Fixture.cs
new file mode 100644
index 00000000000..c5845f0d37b
--- /dev/null
+++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2626/Fixture.cs
@@ -0,0 +1,77 @@
+//------------------------------------------------------------------------------
+//
+// 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.GH2626
+{
+ using System.Threading.Tasks;
+ [TestFixture]
+ public class FixtureAsync : BugTestCase
+ {
+ protected override void OnSetUp()
+ {
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ // The HQL delete does all the job inside the database without loading the entities, but it does
+ // not handle delete order for avoiding violating constraints if any. Use
+ // session.Delete("from System.Object");
+ // instead if in need of having NHibernate ordering the deletes, but this will cause
+ // loading the entities in the session.
+ session.CreateQuery("delete from System.Object").ExecuteUpdate();
+
+ transaction.Commit();
+ }
+ }
+
+ [Test]
+ public async Task SubqueryWithSelectOnSubclassPropertyAsync()
+ {
+ using(var logSpy = new SqlLogSpy())
+ using (var session = OpenSession())
+ {
+ var capabilitiesQuery = session
+ .Query()
+ .Where(x => x.Name == "aaa")
+ .Select(x => x.UserId);
+
+ await (session.Query()
+ .Where(x => capabilitiesQuery.Contains(x.Id))
+ .ToListAsync());
+ Assert.That(logSpy.GetWholeLog(), Does.Contain("UserId").IgnoreCase);
+ }
+ }
+
+ [Test]
+ public async Task SubqueryWithOfTypeAndSelectOnSubclassPropertyAsync()
+ {
+ using(var logSpy = new SqlLogSpy())
+ using (var session = OpenSession())
+ {
+ var capabilitiesQuery = session
+ .Query().OfType()
+ .Where(x => x.Name == "aaa")
+ .Select(x => x.UserId);
+
+ await (session.Query()
+ .Where(x => capabilitiesQuery.Contains(x.Id))
+ .ToListAsync());
+ Assert.That(logSpy.GetWholeLog(), Does.Contain("UserId").IgnoreCase);
+ }
+ }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/GH2626/Entity.cs b/src/NHibernate.Test/NHSpecificTest/GH2626/Entity.cs
new file mode 100644
index 00000000000..478dac60787
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/GH2626/Entity.cs
@@ -0,0 +1,26 @@
+using System;
+
+namespace NHibernate.Test.NHSpecificTest.GH2626
+{
+ abstract class CapabilityAssignment
+ {
+ public virtual Guid Id { get; set; }
+ public virtual string Name { get; set; }
+ }
+
+ class ApplicationUser
+ {
+ public virtual Guid Id { get; set; }
+ public virtual string UserName { get; set; }
+ }
+
+ class RoleCapabilityAssignment : CapabilityAssignment
+ {
+ public virtual Guid RoleId { get; set; }
+ }
+
+ class UserCapabilityAssignment : CapabilityAssignment
+ {
+ public virtual Guid UserId { get; set; }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/GH2626/Fixture.cs b/src/NHibernate.Test/NHSpecificTest/GH2626/Fixture.cs
new file mode 100644
index 00000000000..c613194c552
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/GH2626/Fixture.cs
@@ -0,0 +1,65 @@
+using System.Linq;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.GH2626
+{
+ [TestFixture]
+ public class Fixture : BugTestCase
+ {
+ protected override void OnSetUp()
+ {
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ // The HQL delete does all the job inside the database without loading the entities, but it does
+ // not handle delete order for avoiding violating constraints if any. Use
+ // session.Delete("from System.Object");
+ // instead if in need of having NHibernate ordering the deletes, but this will cause
+ // loading the entities in the session.
+ session.CreateQuery("delete from System.Object").ExecuteUpdate();
+
+ transaction.Commit();
+ }
+ }
+
+ [Test]
+ public void SubqueryWithSelectOnSubclassProperty()
+ {
+ using(var logSpy = new SqlLogSpy())
+ using (var session = OpenSession())
+ {
+ var capabilitiesQuery = session
+ .Query()
+ .Where(x => x.Name == "aaa")
+ .Select(x => x.UserId);
+
+ session.Query()
+ .Where(x => capabilitiesQuery.Contains(x.Id))
+ .ToList();
+ Assert.That(logSpy.GetWholeLog(), Does.Contain("UserId").IgnoreCase);
+ }
+ }
+
+ [Test]
+ public void SubqueryWithOfTypeAndSelectOnSubclassProperty()
+ {
+ using(var logSpy = new SqlLogSpy())
+ using (var session = OpenSession())
+ {
+ var capabilitiesQuery = session
+ .Query().OfType()
+ .Where(x => x.Name == "aaa")
+ .Select(x => x.UserId);
+
+ session.Query()
+ .Where(x => capabilitiesQuery.Contains(x.Id))
+ .ToList();
+ Assert.That(logSpy.GetWholeLog(), Does.Contain("UserId").IgnoreCase);
+ }
+ }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/GH2626/Mappings.hbm.xml b/src/NHibernate.Test/NHSpecificTest/GH2626/Mappings.hbm.xml
new file mode 100644
index 00000000000..cd2fc62f57f
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/GH2626/Mappings.hbm.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/NHibernate/Util/ExpressionsHelper.cs b/src/NHibernate/Util/ExpressionsHelper.cs
index a5874cf94f0..ee6388a9fa2 100644
--- a/src/NHibernate/Util/ExpressionsHelper.cs
+++ b/src/NHibernate/Util/ExpressionsHelper.cs
@@ -697,6 +697,12 @@ protected override Expression VisitQuerySourceReference(QuerySourceReferenceExpr
{
if (node.ReferencedQuerySource is IFromClause fromClause)
{
+ // Types will be different when OfType method is used (e.g. Query().OfType())
+ if (fromClause.ItemType != node.Type)
+ {
+ _convertType = node.Type;
+ }
+
return base.Visit(fromClause.FromExpression);
}