Могу ли я создать пользовательское выражение без использования пункта «Где»?

StackOverflow https://stackoverflow.com/questions/3524101

Вопрос

Хотя я уже решил эту проблему в предыдущем вопросе, используя собственный запрос. Теперь мне интересно, можно ли создать пользовательское выражение, которое можно использовать в критериях без использования пункта «Где? Причина, по которой я не хочу, чтобы пункт о том, где орукл, Oracle connect by ... start with ... (здесь) утверждение. Я последовал за это страница, чтобы начать. Однако это будет генерировать код, как select * from foo where connect by start with...

Вот что я использую. Глядя на то, что генерируется, я могу сказать, что он генерирует правильное утверждение за вычетом предложения «Где».

public class StartWithConnectByCriteria : AbstractCriterion
{
    public StartWithConnectByCriteria(string parentName, string parentValue, string childName)
    {
        ParentName = parentName;
        ParentValue = parentValue;
        ChildName = childName;
    }

    public string ParentName { get; set; }
    public string ParentValue { get; set; }
    public string ChildName { get; set; }
    public IProjection P { get; set; }

    public override IProjection[] GetProjections()
    {
        if(P != null)
        {
            return new IProjection[] {P};
        }
        return null;
    }

    public override TypedValue[] GetTypedValues(ICriteria criteria, ICriteriaQuery criteriaQuery)
    {
        return
            CriterionUtil.GetTypedValues(criteriaQuery, criteria, P, ParentName, ParentValue.ToString());
    }

    public override SqlString ToSqlString(ICriteria criteria, ICriteriaQuery criteriaQuery,
                                          IDictionary<string, IFilter> enabledFilters)
    {
        var sqlBuilder = new SqlStringBuilder();
        SqlString[] parentColumnNames = CriterionUtil.GetColumnNames(ParentName,
                                                               P, criteriaQuery,
                                                               criteria, enabledFilters);
        SqlString parentColumnName = parentColumnNames[0];

        SqlString[] childColumnNames = CriterionUtil.GetColumnNames(ChildName,
                                                   P, criteriaQuery,
                                                   criteria, enabledFilters);
        SqlString childColumnName = childColumnNames[0];

        criteriaQuery.AddUsedTypedValues(GetTypedValues(criteria, criteriaQuery));
        sqlBuilder
            .Add("start with " + parentColumnName + " = '" + ParentValue + "'")
            .Add(" connect by prior " + childColumnName + " = " + parentColumnName);

        return sqlBuilder.ToSqlString();
    }

    public override string ToString()
    {
        return "";
    }
}

Я использую это так.

StartWithConnectByCriteria criterion = 
    new StartWithConnectByCriteria(
        "parent", 
        "parent_value", 
        "child");

DetachedCriteria dc = DetachedCriteria.For<NormalUpstream>("nu")
    .Add(criterion);

У меня такое чувство, что связано с .Add() от отдельной критерии, но не на 100% уверен. К сожалению, я не могу найти много документации о создании пользовательского выражения.

РЕДАКТИРОВАТЬ: Теперь, когда я думаю об этом, похоже, что я лаю не то дерево. Хотя это не важно (у меня уже есть приличная реализация). Мне все еще интересно посмотреть, как я могу дополнительно настроить Nhibernate.

Редактировать 2: Поскольку из коробки Nhibernate не поддерживает запатентованную функцию Oracle, start with ... connect by. Анкет Я пытаюсь узнать больше о расширении Nhibernate, добавив нативную поддержку. Я знаю, что могу зарегистрировать функцию с помощью пользовательского диалекта. Но мне интересно, можно ли реализовать его как критерии, чтобы я мог использовать его с другими запросами критериев. Код, который я опубликовал, работает нормально и правильно создает действительный SQL, но когда я добавляю в свои критерии startwithConnectBycrietia select this_.id from table where start with ... connect by. Анкет Который является неверным запросом, потому что этот пункт не принадлежит тому, где.

Это запрос, который я ожидал, чтобы nhibernate сгенерировал.

select
    random_column
from
    table
start with parent_id = 'parent_node_id'
connect by prior child_up_id = parent_id

Обратите внимание, как нет where пункт в этом запросе. Однако, start with ... connect by все еще можно использовать с where clause. Анкет Вы можете прочитать больше о том, как работают эти ключевые слова здесь.

Это было полезно?

Решение

Я не знаю, разрешает ли существующий синтаксис Nhibernate это, но существует стандартный синтаксис ANSI для иерархических запросов, который может оказаться полезным. Я считаю, что это работает только в 11R2 и выше, однако, поэтому я не уверен, полезно ли это для вас. Видеть Рекурсивный рефакторинг подзадна за дополнительной информацией.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top