سؤال

بينما قمت بالفعل بحل هذه المشكلة في سؤال سابق باستخدام استعلام أصلي. أنا الآن أتساءل عما إذا كان من الممكن إنشاء تعبير مخصص يمكن استخدامه في معايير دون استخدام جملة 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 ٪ متأكد. لسوء الحظ ، لا يمكنني العثور على الكثير من الوثائق حول إنشاء تعبير مخصص.

تحرير: الآن بعد أن فكرت في الأمر يبدو أنني أتنقل على الشجرة الخاطئة. على الرغم من أن هذا ليس أمرًا بالغ الأهمية (لدي بالفعل تنفيذ لائق). ما زلت مهتمًا برؤية كيف يمكنني تخصيص Nhibernate.

تحرير 2: منذ الخروج من الصندوق لا يدعم Nhibernate وظيفة Oracle الملكية ، start with ... connect by. أحاول معرفة المزيد حول تمديد nhibernate عن طريق إضافة الدعم الأصلي لذلك. أنا أدرك أنه يمكنني تسجيل هذه الوظيفة بهجة مخصصة. لكنني أتساءل عما إذا كان من الممكن تنفيذها كمعايير حتى أتمكن من استخدامها مع استعلامات المعايير الأخرى الخاصة بي. يعمل الرمز الذي نشرته بشكل جيد ويقوم بإنشاء SQL ساري المفعول بشكل صحيح ، لكن عندما أضيف startWithConnectBycriteria إلى معايير ، فإن Nhibernate ستصدر استعلامًا مثل 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