Быстрого & Грязного предложение
Грязный хак может работать. По моему опыту, linq2NH переводит запросы на HQL
без особых проверок (см. this question для примерного примера в его примере кода «trick»). Таким образом, вы можете добавить фиктивный и не отображаемый объект public virtual string @class { get; set; }
на свой базовый объект, а затем заказать его.
session.Query<YourBaseEntityType>().OrderBy(e => [email protected]);
Test это, вероятно, было бы перевести «прямо» на рабочий HQL
запроса. Конечно, это некрасиво, может сломаться в любой NH обновления версии, ...
(The @
требуется потому, что class
является зарезервированным словом в C#. Приставка с @
сообщает компилятору, что это просто имя, а не class
ключевое слово.)
уборщик предложение
уборщик способом было бы extend linq2NH для поддержки метода Class()
на ваших лиц. (Сообщение в блоге найдено на this answer to another question Edit:.. Вот еще один интересный implementation example on SO, и вот list of links, который дает гораздо больше информации о linq-to-nhibernate растяжимости)
адаптируя связаны выше «расширения» в блоге в вашем случае, это должно быть что-то как следующие шаги.
Во-первых, вам нужен метод расширения, который можно использовать для ваших объектов. Что-то вроде:
public static class YourLinqExtensions
{
public static string Class(this YourEntityBaseClass source)
{
// .Net runtime implementation just in case, useless in linq2nhib case
return source == null ? null : source.GetType().Name;
}
}
Затем реализует HQL
перевода:
public class ClassGenerator : NHibernate.Linq.Functions.BaseHqlGeneratorForMethod
{
public ClassGenerator()
{
SupportedMethods = new[]
{
NHibernate.Linq.ReflectionHelper.GetMethod(
() => YourLinqExtensions.Class(null))
};
}
public override NHibernate.Hql.Ast.HqlTreeNode BuildHql(MethodInfo method,
Expression targetObject,
ReadOnlyCollection<Expression> arguments,
NHibernate.Hql.Ast.HqlTreeBuilder treeBuilder,
NHibernate.Linq.Visitors.IHqlExpressionVisitor visitor)
{
return treeBuilder.Dot(
// using NHibernate.Hql.Ast; required for .AsExpression() to be found
// at compile time.
visitor.Visit(arguments[0]).AsExpression(),
// Below 'Class' method is not 'YourLinqExtensions.Class' extension
// method. It is natively available on HqlTreeBuilder.
treeBuilder.Class());
}
}
Расширение реестра linq2NH по умолчанию с помощью генератора:
public class YourLinqToHqlGeneratorsRegistry:
NHibernate.Linq.Functions.DefaultLinqToHqlGeneratorsRegistry
{
public YourLinqToHqlGeneratorsRegistry():base()
{
RegisterGenerator(
NHibernate.Linq.ReflectionHelper.GetMethod(
() => YourLinqExtensions.Class(null)),
new ClassGenerator());
}
}
и настроить NH использовать новый реестр. С hibernate.cfg.xml, это должно быть что-то, как добавить следующий property
узел под session-factory
узла:
<property name="linqtohql.generatorsregistry">YourNameSpace.YourLinqToHqlGeneratorsRegistry, YourAssemblyName</property>
Использование:
session.Query<YourBaseEntityType>().OrderBy(e => e.Class());
(С тем, как я разработал все это, он должен в наименее компилируемый, но он полностью непроверен. Edit: теперь он протестирован.)
Похоже, что специальное свойство HQL 'class' для базовых объектов устарело на стороне Hibernate, в пользу функции HQL' type (entityAlias) '. См. Это [doc info notice] (http://docs.jboss.org/hibernate/orm/5.1/userguide/html_single/Hibernate_User_Guide.html#hql-entity-type-exp). Но я не нашел никакой информации о том, что такое позиция NHibernate по этому вопросу. –