Frage

Während ich dieses Thema bereits in einer früheren Frage mit einer nativen Abfrage gelöst habe. Ich frage mich jetzt, ob es möglich ist, einen benutzerdefinierten Ausdruck zu schaffen, die ohne Verwendung der where-Klausel in einem Criteria verwendbar ist? Der Grund, warum ich will nicht die where-Klausel ist, weil Oracle connect by ... start with ... ( hier ) Erklärung. Ich folgte diese Seite meine, um loszulegen. Dies wird jedoch Code wie select * from foo where connect by start with erzeugen ...

Hier ist, was ich verwende. Mit Blick auf, was ich kann erzeugt wird sagen, dass es die richtige Aussage erzeugt abzüglich das where-Klausel.

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 "";
    }
}

Ich bin es so verwendet wird.

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

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

Ich habe das Gefühl, es hat mit dem .Add() vom DetachedCriteria aber nicht 100% sicher zu tun. Leider kann ich nicht scheinen, viel Dokumentation über das Erstellen eines benutzerdefinierten Ausdruck zu finden.

Edit: Nun, da ich darüber nachdenke sieht aus wie ich den Holzweg bin. Zwar ist dies nicht entscheidend ist (ich habe schon eine ordentliche Umsetzung). Ich bin immer noch daran interessiert zu sehen, wie ich kann weiter NHibernate anpassen.

Edit 2: Da aus der Box NHibernate unterstützt keine Oracle-eigene Funktion, start with ... connect by. Ich versuche, von NHibernate mehr über Verlängerung zu lernen für sie das Hinzufügen native Unterstützung. Ich bin mir bewusst, ich diese Funktion mit einem benutzerdefinierten Dialekt registrieren. Aber ich frage mich, ob es möglich ist, es als Kriterium zu implementieren, damit ich es mit meinen anderen Kriterien Abfragen verwenden kann. Der Code habe ich geschrieben funktioniert gut und schafft richtig gültige SQL, aber wenn ich hinzufügen StartWithConnectByCriteria meiner Kriterien, NHibernate werden Fragen eine Abfrage wie select this_.id from table where start with ... connect by. Welches ist eine ungültige Abfrage, da diese Klausel gehört nicht mit dem, wo.

Dies ist die Abfrage, die ich erwarten würde für NHibernate zu erzeugen.

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

Beachten Sie, wie es ist keine where Klausel in dieser Abfrage. Allerdings könnte start with ... connect by noch mit einem where clause verwendet werden. Sie können mehr darüber lesen, wie diese Keywords arbeiten hier .

War es hilfreich?

Lösung

Ich weiß nicht, ob die vorhandene NHibernate Syntax für diese erlaubt, aber es ist eine ANSI-Standard-Syntax für hierarchische Abfragen, die als nützlich erweisen können. Ich glaube, es funktioniert nur in 11R2 und oben, aber so bin ich nicht sicher, ob es für Sie geeignet ist. Siehe rekursive Subquery Refactoring für weitere Informationen .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top