質問

ネイティブクエリを使用して、以前の質問でこの問題をすでに解決しましたが。私は今、Where句を使用せずに基準で使用できるカスタム式を作成することが可能かどうか疑問に思っていますか?私が句を望まない理由は、オラクルが 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%確信はありません。残念ながら、カスタム表現の作成に関する多くのドキュメントを見つけることができないようです。

編集:今、私はそれについて考えているので、私は間違った木をbarえているように見えます。これは重要ではありませんが(私はすでにまともな実装があります)。 Nhibernateをさらにカスタマイズする方法をまだ見ることに興味があります。

編集2:ボックスから外れているため、NhibernateはOracleの独自の機能をサポートしていないため、 start with ... connect by. 。ネイティブサポートを追加することにより、Nhibernateの拡張についてさらに学びようとしています。それらの機能をカスタム方言で登録できることを知っています。しかし、他の基準クエリで使用できるように、基準としてそれを実装できるかどうか疑問に思っています。私が投稿したコードは正常に動作し、有効なSQLを正しく作成しますが、StartWithConnectByCriteriaを自分の基準に追加すると、Nhibernateは次のようなクエリを発行します select this_.id from table where start with ... connect by. 。その条項はwhereに属していないため、これは無効なクエリです。

これは、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