2014-10-16 1 views
0

мне нужно написать это в NHibernate Criteria как проекции:запись Round в критериях NHibernate

В subAlias ​​_выключена_ корневой псевдоним, так {псевдоним} не может заменить правильный псевдоним SQL, и моя проблема что другие части запроса делает subAlias ​​варьироваться в сгенерированном SQL

ROUND(alias.Property/parameterValueFromMethodParameter + ", 0) 
    * parameterValueFromMethodParameter2 AS SQLAlias 

Это как далеко (в выключенном состоянии) я получил:

.Add(Projections.SqlFunction(new VarArgsSQLFunction("(", "/", ")") 
    , NHibernateUtil.Int32 
    , Projections.SqlFunction("round" 
      , NHibernateUtil.Decimal 
      , Projections.Property("subAlias.Property"))), "SQLAlias")) 

В результате получается следующий код SQL:

ROUND(subAlias3(4).Property 
      )AS y1_ 

Кто-нибудь есть опыт работы с проекциями, как это? Я нашел это patch i hibernate, но похоже, что он не был реализован.

+0

Я попытался улучшить форматирование, но вы действительно должны пройти через фрагменты кода, которые вы прошли редактор Они, похоже, не работают ... –

+0

oh, спасибо за форматирование :) Это был просто пример кода «psuedo», а не рабочий код ... –

ответ

0

Я решил, написав свой собственный SQL IProjection. С помощью litte помощи от this example.

public SqlString ToSqlString(ICriteria criteria, int loc, ICriteriaQuery criteriaQuery, IDictionary<string, IFilter> enabledFilters) 
    { 
     string replacedString = Regex.Replace(
      this.sql, 
      @"{([a-zA-Z_]((\.)?[a-zA-Z0-9_])*)}", 
      m => 
       { 
        ICriteria critter = criteria.GetCriteriaByAlias(m.Groups[1].Value); 
        if (critter != null) 
        { 
         return criteriaQuery.GetSQLAlias(critter); 
        } 

        return m.Groups[0].Value; 
       }); 

     return new SqlString(replacedString); 
    } 

Так что теперь я могу сделать (В SqlGroupProjection):

ROUND({subAlias}.XCoord/" + aggregationSize + ", 0) * " + aggregationSize + " AS SQLAlias 

Есть некоторые другие попытки на расширение (N) Hibernate для обработки этого псевдонима в нестандартных проблемах SQL:

Expression.Sql should support aliases other than {alias}
Support for referencing non-root entities in Criteria SQL expressions

1

Если я правильно понимаю ваш пример правильно, самым простым решением было бы использовать проекцию SQL:

// the parameterValueFromMethodParameter 
// and parameterValueFromMethodParameter2 
var computationParams = new object[] {2, 4}; // just an example numbers 

// SQL To be generated 
// see that here we work with COLUMN name, not property 
var sqlSnippet = " (ROUND({{alias}}.ColumnName/{0}, 0) * {1}) AS computed "; 

// put that all together 
var projectSql = string.Format(sqlSnippet, computationParams); 

// IProjection 
var projection = Projections.SqlProjection(projectSql, new string[0], new IType[0]); 

// add it to SELECT clause 
criteria.SetProjection(Projections.ProjectionList() 
      .Add(projection) 
      ... 
     ); 

Это должно работать ...

+0

Моя проблема в том, что {alias} не является корневым псевдонимом, это псевдоним для другой таблицы. Поэтому я не могу заставить NH заменить {alias} на корректный сгенерированный псевдоним sql. Я обновил вопрос. –

+0

Ну в основном, это просто выходит за рамки стандартного ORM. Один из способов может заключаться в том, чтобы зависеть от * почти всегда одного и того же псевдонима * для не корневой таблицы (например, notRoot3_). Или создайте пользовательский SQL-подзапрос с фильтром {alias} .ID ... Но так или иначе. Это вряд ли можно отметить как стандартное требование для запроса ORM ... извините .. –

+0

Это далеко не стандартный! Я согласен, но у нас есть большой поисковый запрос, построенный на критериях, и он добавляет псевдонимы в зависимости от выбора пользователя, чтобы иметь возможность искать в разных полях. Поэтому, даже если это не стандартно, нам нужно его решить :) –