diff --git a/src/NHibernate.Test/Async/NHSpecificTest/GH2707/FixtureByCode.cs b/src/NHibernate.Test/Async/NHSpecificTest/GH2707/FixtureByCode.cs
new file mode 100644
index 00000000000..ed8a151bd42
--- /dev/null
+++ b/src/NHibernate.Test/Async/NHSpecificTest/GH2707/FixtureByCode.cs
@@ -0,0 +1,72 @@
+//------------------------------------------------------------------------------
+//
+// 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 NHibernate.Cfg.MappingSchema;
+using NHibernate.Mapping.ByCode;
+using NUnit.Framework;
+using NHibernate.Linq;
+
+namespace NHibernate.Test.NHSpecificTest.GH2707
+{
+ using System.Threading.Tasks;
+ [TestFixture]
+ public class ConditionalFixtureAsync : TestCaseMappingByCode
+ {
+ protected override HbmMapping GetMappings()
+ {
+ var mapper = new ModelMapper();
+
+ mapper.AddMapping();
+ return mapper.CompileMappingForAllExplicitlyAddedEntities();
+ }
+
+ protected override void OnSetUp()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ var e1 = new Entity1() {Id = "id1", IsChiusa = true};
+ e1.CustomType = new MyType() {ToPersist = 1};
+ session.Save(e1);
+ var e2 = new Entity1() {Id = "id2", IsChiusa = false};
+ session.Save(e2);
+ e1.Parent = e1;
+ transaction.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ session.CreateQuery("delete from System.Object").ExecuteUpdate();
+ transaction.Commit();
+ }
+ }
+
+ [Test]
+ public async Task EntityAndCustomTypeInConditionalResultAsync()
+ {
+ using (var s = OpenSession())
+ await ((from x in s.Query()
+ let parent = x.Parent
+ //NH-3005 - Contditional on custom type
+ where (parent.IsChiusa ? x.CustomType : parent.CustomType) == x.CustomType
+ select new
+ {
+ ParentIsChiusa = (((x == null) ? null : x.Parent) == null)
+ ? (bool?) null
+ : x.Parent.IsChiusa,
+ }).ToListAsync());
+ }
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/GH2707/Entity.cs b/src/NHibernate.Test/NHSpecificTest/GH2707/Entity.cs
new file mode 100644
index 00000000000..46d557151d7
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/GH2707/Entity.cs
@@ -0,0 +1,139 @@
+using System;
+using System.Data.Common;
+using NHibernate.Engine;
+using NHibernate.Mapping.ByCode.Conformist;
+using NHibernate.SqlTypes;
+using NHibernate.UserTypes;
+
+namespace NHibernate.Test.NHSpecificTest.GH2707
+{
+ public class Entity1
+ {
+ public virtual string Id { get; set; }
+ public virtual bool IsChiusa { get; set; }
+ public virtual MyType CustomType { get; set; }
+ public virtual Entity1 Parent { get; set; }
+ }
+
+ class Entity1Map : ClassMapping
+ {
+ public Entity1Map()
+ {
+ Table("TA");
+
+ Id(x => x.Id);
+ Property(x => x.IsChiusa);
+ Property(x => x.CustomType, m => m.Type());
+ ManyToOne(x => x.Parent, x => x.ForeignKey("none"));
+ }
+ }
+
+ public class MyType
+ {
+ public int ToPersist { get; set; }
+
+ public override bool Equals(object obj)
+ {
+ if (obj == null || GetType() != obj.GetType())
+ {
+ return false;
+ }
+
+ var other = (MyType) obj;
+ return ToPersist == other.ToPersist;
+ }
+
+ public override int GetHashCode()
+ {
+ return ToPersist.GetHashCode();
+ }
+ }
+
+ public class SimpleCustomType : IUserType
+ {
+ private static readonly SqlType[] ReturnSqlTypes = {SqlTypeFactory.Int32};
+
+ #region IUserType Members
+
+ public new bool Equals(object x, object y)
+ {
+ if (ReferenceEquals(x, y))
+ {
+ return true;
+ }
+
+ if (ReferenceEquals(null, x) || ReferenceEquals(null, y))
+ {
+ return false;
+ }
+
+ return x.Equals(y);
+ }
+
+ public int GetHashCode(object x)
+ {
+ return (x == null) ? 0 : x.GetHashCode();
+ }
+
+ public SqlType[] SqlTypes
+ {
+ get { return ReturnSqlTypes; }
+ }
+
+ public object DeepCopy(object value)
+ {
+ return value;
+ }
+
+ public void NullSafeSet(DbCommand cmd, object value, int index, ISessionImplementor session)
+ {
+ if (value == null)
+ {
+ cmd.Parameters[index].Value = DBNull.Value;
+ }
+ else
+ {
+ cmd.Parameters[index].Value = ((MyType) value).ToPersist;
+ }
+ }
+
+ public System.Type ReturnedType
+ {
+ get { return typeof(Int32); }
+ }
+
+ public object NullSafeGet(DbDataReader rs, string[] names, ISessionImplementor session, object owner)
+ {
+ int index0 = rs.GetOrdinal(names[0]);
+ if (rs.IsDBNull(index0))
+ {
+ return null;
+ }
+
+ int value = rs.GetInt32(index0);
+ return new MyType {ToPersist = value};
+ }
+
+ public bool IsMutable
+ {
+ get { return false; }
+ }
+
+ public object Replace(object original, object target, object owner)
+ {
+ return original;
+ }
+
+ public object Assemble(object cached, object owner)
+ {
+ return cached;
+ }
+
+ public object Disassemble(object value)
+ {
+ return value;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/NHibernate.Test/NHSpecificTest/GH2707/FixtureByCode.cs b/src/NHibernate.Test/NHSpecificTest/GH2707/FixtureByCode.cs
new file mode 100644
index 00000000000..36809f21220
--- /dev/null
+++ b/src/NHibernate.Test/NHSpecificTest/GH2707/FixtureByCode.cs
@@ -0,0 +1,60 @@
+using System.Linq;
+using NHibernate.Cfg.MappingSchema;
+using NHibernate.Mapping.ByCode;
+using NUnit.Framework;
+
+namespace NHibernate.Test.NHSpecificTest.GH2707
+{
+ [TestFixture]
+ public class ConditionalFixture : TestCaseMappingByCode
+ {
+ protected override HbmMapping GetMappings()
+ {
+ var mapper = new ModelMapper();
+
+ mapper.AddMapping();
+ return mapper.CompileMappingForAllExplicitlyAddedEntities();
+ }
+
+ protected override void OnSetUp()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ var e1 = new Entity1() {Id = "id1", IsChiusa = true};
+ e1.CustomType = new MyType() {ToPersist = 1};
+ session.Save(e1);
+ var e2 = new Entity1() {Id = "id2", IsChiusa = false};
+ session.Save(e2);
+ e1.Parent = e1;
+ transaction.Commit();
+ }
+ }
+
+ protected override void OnTearDown()
+ {
+ using (var session = OpenSession())
+ using (var transaction = session.BeginTransaction())
+ {
+ session.CreateQuery("delete from System.Object").ExecuteUpdate();
+ transaction.Commit();
+ }
+ }
+
+ [Test]
+ public void EntityAndCustomTypeInConditionalResult()
+ {
+ using (var s = OpenSession())
+ (from x in s.Query()
+ let parent = x.Parent
+ //NH-3005 - Conditional with custom type
+ where (parent.IsChiusa ? x.CustomType : parent.CustomType) == x.CustomType
+ select new
+ {
+ ParentIsChiusa = (((x == null) ? null : x.Parent) == null)
+ ? (bool?) null
+ : x.Parent.IsChiusa,
+ }).ToList();
+ }
+ }
+}
diff --git a/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionVisitor.cs b/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionVisitor.cs
index 2a285ff5311..63d9d3e2a1e 100644
--- a/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionVisitor.cs
+++ b/src/NHibernate/Linq/Visitors/HqlGeneratorExpressionVisitor.cs
@@ -622,7 +622,7 @@ protected HqlTreeNode VisitConditionalExpression(ConditionalExpression expressio
// If both operands are parameters, HQL will not be able to determine the resulting type before
// parameters binding. But it has to compute result set columns type before parameters are bound,
// so an artificial cast is introduced to hint HQL at the resulting type.
- return expression.Type == typeof(bool) || expression.Type == typeof(bool?)
+ return expression.Type == typeof(bool) || expression.Type == typeof(bool?) || !HqlIdent.SupportsType(expression.Type)
? @case
: _hqlTreeBuilder.TransparentCast(@case, expression.Type);
}