Domanda

Anche se ho già risolto questo problema in una domanda precedente utilizzando una query nativo. Ora sto chiedendo se è possibile creare un'espressione personalizzata che è utilizzabile in una Criteri senza utilizzare la clausola dove? Il motivo per cui non voglio la clausola where è perché connect by ... start with ... di Oracle ( qui ) dichiarazione. Ho seguito questo pagina per ottenere il mio iniziato. Tuttavia, questo genererà il codice come select * from foo where connect by start with ...

Ecco quello che sto usando. Guardando ciò che viene generato posso dire che si sta generando l'affermazione corretta meno la clausola where.

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

io sto usando in questo modo.

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

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

Ho la sensazione che ha a che fare con la .Add() dal DetachedCriteria ma non sicuro al 100%. Purtroppo, non riesco a trovare molta documentazione sulla creazione di un'espressione personalizzata.

Edit: Ora che ci penso su di esso sembra che io sto abbaiare contro l'albero sbagliato. Anche se questo non è determinante (ho già un implementazione decente). Sono ancora interessato a vedere come posso personalizzare ulteriormente NHibernate.

Modifica 2: Dal momento che fuori dalla scatola NHibernate non supporta la funzione di proprietà di Oracle, start with ... connect by. Sto cercando di imparare di più su l'estensione NHibernate aggiungendo il supporto nativo per esso. Sono consapevole che posso registrare coloro funzione con un dialetto personalizzato. Ma mi chiedo se è possibile per la sua attuazione come criterio di modo da poter utilizzare con i miei altri criteri di query. Il codice che ho postato funziona bene e crea correttamente SQL valido, ma quando aggiungo StartWithConnectByCriteria ai miei criteri, NHibernate questioni saranno una query come select this_.id from table where start with ... connect by. Il che è una query valida perché tale clausola non appartiene al dove.

Questa è la domanda che ci si aspetta per NHibernate per generare.

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

Si noti come non v'è alcuna clausola di where in questa query. Tuttavia, start with ... connect by potrebbe ancora essere utilizzato con un where clause. Si può leggere di più su come funzionano tali parole chiave qui .

È stato utile?

Soluzione

Non so se la sintassi NHibernate esistente consente per questo, ma v'è una sintassi standard ANSI per le query gerarchiche che possono rivelarsi utili. Credo che funziona solo in 11R2 e, soprattutto, però, quindi non sono sicuro se è utile per voi. Vedere ricorsivo sottoquery refactoring per ulteriori informazioni .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top