У меня есть NHibernate QueryOver, который генерирует ошибку sql: Элементы ORDER BY должны появляться в списке выбора, если указано SELECT DISTINCT
Проблема вызвана SQL-проекцией Iиспользую чтобы выбрать, где и упорядочить.Поскольку сама проекция использует функцию sql, у нее есть параметры (константа: пробел).
При использовании проекции, назначенной переменной, NH переводит каждое использование этой переменной уникально в sql, что означает, что каждое получает своеновый параметр sql.Sql поэтому думает, что заявления разные.Я пытался безрезультатно использовать псевдонимы для проекций, но, похоже, нет способа сделать это с помощью QueryOver.
Потеряно для идей, отличных от возврата к API Criteria.
Этоупрощенный код QueryIOver:
var projection = ContactOrCompanyName();
return Session.QueryOver<Contact>()
.Select(
Projections.Distinct(
Projections.ProjectionList()
.Add(Projections.Property<Contact>(x => x.Id).As("ContactId"))
.Add(projection)
)
)
.TransformUsing(Transformers.AliasToBean<ContactDto>())
.OrderBy(projection).Asc;
private IProjection ContactOrCompanyName
{
get
{
return Projections.SqlFunction(
"coalesce",
NHibernateUtil.String,
Projections.Property<Contact>(c => c.CompanyName),
Projections.SqlFunction(
"concat",
NHibernateUtil.String,
Projections.Property<Contact>(c => c.FirstName),
Projections.Constant(" "),
Projections.Property<Contact>(c => c.LastName)
)
);
}
}
приводит к следующему sql:
SELECT distinct
this_.CONTACT_ID as y0_,
coalesce(this_.COMPANY_NM, (this_.FIRST_NM+@p0+this_.LAST_NM)) as y1_
FROM dbo.ADD_CONTACT this_
ORDER BY coalesce(this_.COMPANY_NM, (this_.FIRST_NM+@p1+this_.LAST_NM)) asc
Похоже, что Criteria API действительно поддерживает повторное использование псевдонимов в этом примере:
IList results = session.CreateCriteria(typeof(DomesticCat), "cat")
.CreateAlias("kittens", "kit")
.SetProjection( Projections.ProjectionList()
.Add( Projections.Property("cat.Name"), "catName" )
.Add( Projections.Property("kit.Name"), "kitName" )
)
.AddOrder( Order.Asc("catName") )
.AddOrder( Order.Asc("kitName") )
.List();
Так где же это в QueryOver?