Pregunta

Si bien ya he resuelto este problema en una pregunta anterior mediante una consulta nativa. Ahora estoy preguntando si es posible crear una expresión personalizada que se puede utilizar en un Criterios sin necesidad de utilizar la cláusula where? La razón por la que no quiero la cláusula where se debe a connect by ... start with ... de Oracle ( aquí ) comunicado. Seguí este página para conseguir mi comenzó. Sin embargo, esto generará un código como select * from foo where connect by start with ...

Esto es lo que estoy utilizando. En cuanto a lo que se genera lo que puedo decir que está generando la afirmación correcta menos la cláusula 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 "";
    }
}

lo estoy usando como este.

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

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

Tengo la sensación de que tiene que ver con la .Add() del DetachedCriteria pero no es 100% seguro. Por desgracia, parece que no puedo encontrar mucha documentación sobre la creación de una expresión personalizada.

Edit: Ahora que lo pienso parece que estoy ladrando al árbol equivocado. Si bien esto no es crucial (Ya tengo una aplicación decente). Todavía estoy interesado en ver cómo puedo personalizar aún más NHibernate.

Edición 2: Desde fuera de la caja NHibernate no soporta la función de propiedad de Oracle, start with ... connect by. Estoy tratando de aprender más acerca de la ampliación NHibernate añadiendo soporte nativo para ello. Soy consciente de que puedo registrar aquellos función con un dialecto personalizado. Pero me pregunto si es posible implementarlo como un criterio para que pueda usarlo con mis otras consultas de criterios. El código que ha escrito correctamente y funciona bien crea SQL válida, pero cuando agrego StartWithConnectByCriteria a mis criterios, NHibernate voluntad problemas de una consulta como select this_.id from table where start with ... connect by. ¿Qué es una consulta no válida debido a que la cláusula no pertenece al lugar.

Esta es la pregunta que cabe esperar de NHibernate para generar.

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

Observe cómo no hay ninguna cláusula where en esta consulta. Sin embargo, start with ... connect by todavía podría ser utilizado con una where clause. Puede leer más sobre cómo funcionan las palabras clave aquí .

¿Fue útil?

Solución

No sé si la sintaxis NHibernate existente permite para esto, pero hay una sintaxis estándar ANSI para consultas jerárquicas que pueden resultar útiles. Creo que sólo funciona en 11R2 y por encima, sin embargo, así que no estoy seguro de si es útil para usted. Ver recursiva Subconsulta Refactoring para más información .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top