使用函数查询Max

时间:2014-11-26 10:14:53

标签: c# nhibernate fluent-nhibernate queryover

我尝试在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中使用它。

1 个答案:

答案 0 :(得分:1)

你很亲密:

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>();