I couldn't find anything either so I created my own criterion to do it.
Code:
using System.Collections;
using global::NHibernate;
using global::NHibernate.Engine;
using global::NHibernate.Expression;
using global::NHibernate.Hql.Util;
using global::NHibernate.Persister.Entity;
using global::NHibernate.SqlCommand;
using global::NHibernate.Type;
public class IsAExpression : AbstractCriterion
{
private readonly Type _entityClass;
private readonly string _propertyNameOrAlias;
public IsAExpression(Type entityClass)
: this(string.Empty, entityClass)
{
}
public IsAExpression(string propertyNameOrAlias, Type entityClass)
{
_propertyNameOrAlias = propertyNameOrAlias;
_entityClass = entityClass;
}
public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery,
IDictionary enabledFilters)
{
string alias;
Type targetType;
ICriteria aliasedCriteria;
if (string.IsNullOrEmpty(_propertyNameOrAlias))
{
alias = criteriaQuery.GetSQLAlias(criteria);
targetType = criteriaQuery.GetEntityName(criteria);
}
else if ((aliasedCriteria = criteria.GetCriteriaByAlias(_propertyNameOrAlias)) != null)
{
alias = criteriaQuery.GetSQLAlias(aliasedCriteria);
targetType = criteriaQuery.GetEntityName(aliasedCriteria);
}
else
{
alias = criteriaQuery.GetSQLAlias(criteria, _propertyNameOrAlias);
IType type = criteriaQuery.GetTypeUsingProjection(criteria, _propertyNameOrAlias);
if (!type.IsEntityType)
{
throw new QueryException("Only entities can be used with an IsAExpression");
}
targetType = type.ReturnedClass;
}
if (!targetType.IsAssignableFrom(_entityClass))
{
return new SqlString("1=0");
}
IQueryable queryable = ObtainQueryable(criteriaQuery);
SqlString condition = queryable.QueryWhereFragment(alias, true, true);
if (condition.IndexOfCaseInsensitive(" and ") == 0)
{
condition = condition.Substring(5);
}
return (condition.Length > 0) ? condition : new SqlString("1=1");
}
public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery)
{
return EmptyTypes;
}
public override string ToString()
{
return _propertyNameOrAlias + " isa (" + _entityClass.FullName + ')';
}
public static IsAExpression Create(Type entityClass)
{
return new IsAExpression(entityClass);
}
public static IsAExpression Create<T>()
{
return new IsAExpression(typeof(T));
}
public static IsAExpression Create(string propertyNameOrAlias, Type entityClass)
{
return new IsAExpression(propertyNameOrAlias, entityClass);
}
public static IsAExpression Create<T>(string propertyNameOrAlias)
{
return new IsAExpression(propertyNameOrAlias, typeof(T));
}
private IQueryable ObtainQueryable(ICriteriaQuery criteriaQuery)
{
IQueryable queryable = criteriaQuery.Factory.GetEntityPersister(_entityClass) as IQueryable;
if (queryable == null)
{
queryable = SessionFactoryHelper.FindQueryableUsingImports(
criteriaQuery.Factory, _entityClass.FullName);
}
return queryable;
}
private static readonly TypedValue[] EmptyTypes = new TypedValue[0];
}