使用函数查询 Max

本文关键字:Max 查询 函数 | 更新日期: 2023-09-27 18:31:58

我尝试在nHibernate中构造此查询:

SELECT max(split_part(person.Name,'-',2)) 
FROM   data.person

如何使用投影来做到这一点?

我现在有这个:

session.QueryOver<PersonEntity>()
                          .Select(Projections.Max<PersonEntity>(x=>Projections.SqlFunction("split_part", NHibernateUtil.String, Projections.Property<PersonEntity>(p=>p.Name), Projections.Constant("-"), Projections.Constant(2))))
                          .SingleOrDefault<int>()

但我可以让它在 nHibernate 中工作。

使用函数查询 Max

你很接近:

session.QueryOver<PersonEntity>()
    .Select(
        Projections.Max(
            Projections.SqlFunction(
                new SQLFunctionTemplate(
                    NHibernateUtil.String,
                    "split_part(?1, ?2, ?3)"),
                NHibernateUtil.String,
                Projections.Property<PersonEntity>(p => p.Name),
                Projections.Constant("-"),
                Projections.Constant(2))))
    .SingleOrDefault<int>();

你也可以通过用你自己的方言注册函数来清理一下(我假设你使用的是PostgreSQL:

public class CustomPostgresDialect : PostgreSQLDialect
{
    public CustomPostgresDialect()
    {
        this.RegisterFunction(
            "split_part",
            new SQLFunctionTemplate(
                NHibernateUtil.String,
                "split_part(?1, ?2, ?3"));
    }
}

然后在配置文件中改用该方言。

然后,您可以添加自己的自定义方法来调用 split_part 方法:

public static class ProjectionExtensions
{
    public static IProjection SplitPart<T>(
        Expression<Func<T, object>> expression,
        string delimiter, 
        int field)
    {
        return Projections.SqlFunction(
            "split_part",
            NHibernateUtil.String,
            Projections.Property<T>(expression),
            Projections.Constant(delimiter),
            Projections.Constant(field));
    }
} 

然后,您的查询最终看起来会更干净一些:

session.QueryOver<PersonEntity>()
    .Select(
        Projections.Max(
            ProjectionExtensions.SplitPart<Person>(p => p.FullName, "-", 2)))
    .SingleOrDefault<int>();