我有以下查询:
var result = _session.QueryOver<Entity>()
.Where(e => e.Property == value)
.SelectList(list => list
.Select(f => Projections.Concat("prefix-", e.BigIntProperty)).WithAlias(() => alias.Whatever)
...
)
.TransformUsing(Transformers.AliasToBean<Model>())
.Future<Model>();
问题是Projections.Concat()
只接受字符串而且e.BigIntProperty
不接受,上面的内容不会编译。有没有办法将e.BigIntProperty
转换为字符串?
我尝试了类似下面的内容,但它们都不起作用:
.Select(f => Projections.Concat("prefix-", Projection.Cast(NHibernateUtil.String, e.BigIntProperty))).WithAlias(() => alias.Whatever)
,因为Projections.Cast
会返回IProjection
而不是字符串。
答案 0 :(得分:3)
Projections.Cast
似乎非常有限,因为它不能随意Projection
。幸运的是,您可以轻松创建自己的自定义投影,使您能够这样做:
public static class CustomProjections
{
public static IProjection Concat(params IProjection[] projections)
{
return Projections.SqlFunction(
"concat",
NHibernateUtil.String,
projections);
}
}
然后,您就可以像这样使用CustomProjections
课程了:
var result = _session.QueryOver<Entity>()
.Where(e => e.Property == value)
.SelectList(list => list
.Select(CustomProjections.Concat(
Projections.Constant("prefix-"),
Projections.Cast(
NHibernateUtil.String,
Projections.Property<Entity>(e => e.BigIntProperty))))
.WithAlias(() => alias.Whatever)
...
)
.TransformUsing(Transformers.AliasToBean<Model>())
.Future<Model>();
答案 1 :(得分:2)
我已经接受了安德鲁的答案,但仅供参考,您可以直接使用Projections.SqlFunction("concat", ...)
解决整个问题,因为它可以将IProjection
作为参数而不仅仅是字符串。
var result = _session.QueryOver<Entity>()
.Where(e => e.Property == value)
.SelectList(list => list
.Select(Projections.SqlFunction("concat",
NHibernateUtil.String,
Projections.Constant("prefix-"),
Projections.Cast(NHibernateUtil.String, Projections.Property<Entity>(e => e.BigIntProperty))))
.WithAlias(() => alias.Whatever)
...
)
.TransformUsing(Transformers.AliasToBean<Model>())
.Future<Model>();
注意:似乎在调用Projections.Concat(...)
或Projections.SqlFunction("concat", ...)
时,生成的查询实际上使用+
运算符,例如:
SELECT (a + b) as foo FROM table
而不是:
SELECT concat(a, b) as foo FROM table
当然,CONCAT
仅适用于MS SQL Server 2012及更高版本,因此这是正确的。可能MsSQl2012Dialect
可以使用CONCAT
,因为 CONCAT
不要求参数是varchar,它们也可能是整数。
不幸的是MsSQl2012Dialect
没有这样做,但是构建自定义方言非常容易:
public class CustomMsSql2012Dialect : MsSql2012Dialect
{
protected override void RegisterFunctions()
{
base.RegisterFunctions();
base.RegisterFunction("concat", new VarArgsSQLFunction(NHibernateUtil.String, "concat(", ",", ")"));
}
}
因此,如果您使用的是2012版或更高版本并且您将上述内容声明为Dialect
,则可以放弃Projections.Cast(...)
部分