gpt4 book ai didi

NHIbernate 3.0 - QueryOver,使用具有不同和顺序的相同投影会引发 sql 错误

转载 作者:行者123 更新时间:2023-12-04 06:05:46 30 4
gpt4 key购买 nike

我有一个 NHibernate QueryOver 正在生成 sql 错误:如果指定了 SELECT DISTINCT,则 ORDER BY 项必须出现在选择列表中

问题是由我用来选择、位置和排序的 sql 投影引起的。因为投影本身使用了一个sql函数,所以它有参数(一个常量:空格)。

当使用分配给变量的投影时,NH 将此变量的每次使用都唯一地转换为 sql,这意味着每个使用都有自己的新 sql 参数。 Sql 因此认为语句是不同的。我曾尝试使用别名进行投影但无济于事,但似乎无法使用 QueryOver 做到这一点。

除了转回 Criteria API 之外,其他想法也有些失落。

这是 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 中的什么地方呢?

最佳答案

这有点hacky,但它有效。通过创建两个投影,一个用于比较,一个用于选择,我们可以停止 SQL 提示投影顺序未包含在选择列表中:

      CompanyDirectorDto dtoAlias = null;
var contactsQuery = Session.QueryOver<Contact>()
.Select(
Projections.Distinct(
Projections.ProjectionList()
.Add(Projections.Property<Contact>(x => x.Id).WithAlias(() => dtoAlias.ContactId))
.Add(ContactOrCompanyNameComparer)
.Add(ContactOrCompanyNameSelector.WithAlias(() => dtoAlias.ContactDisplayName))
)
)
.TransformUsing(Transformers.AliasToBean<CompanyDirectorDto>())
.OrderBy(ContactOrCompanyNameComparer).Asc;

private IProjection ContactOrCompanyNameSelector
{
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)
)
);
}
}

private IProjection ContactOrCompanyNameComparer
{
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.Property<Contact>(c => c.LastName)
)
);
}
}

关于NHIbernate 3.0 - QueryOver,使用具有不同和顺序的相同投影会引发 sql 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8385740/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com