2014-11-26 2 views
1

Я пытаюсь построить этот запрос в NHibernate:Query над Max с функцией

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

Вы близки:

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

Хорошая идея спасибо :) Я постараюсь его. – user3511244

Смежные вопросы