كيف يمكنني التعامل مع قائمة معلمات ربما فارغة عند استخدام استعلام مسمى في Nhibernate؟

StackOverflow https://stackoverflow.com/questions/3700392

سؤال

أواجه مشكلات في التعامل مع الموقف حيث تكون قائمة المعلمات المرسلة إلى استعلام مسمى في Nhibernate فارغًا.

هذا مثال على وضعي:

<sql-query name="MyClass_FilterByCategoryID">
    <return alias="MyClass" class="MyProject.BusinessEntities.MyClassBE"/>
    <![CDATA[
    SELECT DISTINCT MyClass.*
    FROM MyClassTable MyClass
    WHERE 1 = 1
            AND MyClassTable.CategoryID NOT IN (:categoryIDs) 
    ]]>
</sql-query>

هذه هي الطريقة التي تسمى:

public IList<MyClassBE> FilterByCategoryID(List<String> categoryIDs)
{
    return session.GetNamedQuery("MyClass_FilterByCategoryID")
        .SetParameterList("categoryIDs", categoryIDs)
        .List<MyClassBE>();
}

ومع ذلك ، عندما أقوم بتمرير قائمة فارغة بالطريقة ، أحصل على هذا الخطأ:

System.NullReferenceException: لم يتم تعيين مرجع الكائن على مثيل لكائن.

تتبع مكدس الخادم:

في nhibernate.engine.typedvalue..ctor (نوع itype ، قيمة الكائن ، entitymode entitymode) في c: srctions bs 3rdparty nhibernate.2.1.2.ga-src src nhibernate 25

في nhibernate.impl.abstractqueryimpl.setparameterlist (اسم السلسلة ، icollection vals ، نوع itype) في c: injections bs 3rdparty nhibernate.2.1.2.ga-src src nhibernate

في nhibernate.impl.abstractqueryimpl.setparameterlist (اسم السلسلة ، icollection vals) في c: الوصلات bs 3rdparty nhibernate.2.1.2.ga-src src nhibernate

في myproject.dao.myclassdao.filterbycategoryId (List`1 Catevoryids) في myclassdao.cs: السطر 50

ماذا ستكون أفضل طريقة لحل هذا؟ يرجى ملاحظة أن الاستعلام المسماة بالطبع أكثر تعقيدًا بكثير من الاستعلام الموضح أعلاه ، لذلك أود تجنب نسخه إلى إصدار ثانٍ لا يستخدم قائمة المعلمات.

هل كانت مفيدة؟

المحلول

لقد واجهت نفس المشكلة ، لذا فأنا بحاجة إلى مشاركة الحل:

تعديل استعلامك إلى:

<sql-query name="MyClass_FilterByCategoryID">
    <return alias="MyClass" class="MyProject.BusinessEntities.MyClassBE"/>
    <![CDATA[
    SELECT DISTINCT MyClass.*
    FROM MyClassTable MyClass
    WHERE 
            (
              :hasCatogories=0
              or (:hasCatogories=1 and MyClassTable.CategoryID NOT IN (:categoryIDs) )
            )
    ]]>
</sql-query>

والرمز إلى:

public IList<MyClassBE> FilterByCategoryID(List<String> categoryIDs)
{
    return session.GetNamedQuery("MyClass_FilterByCategoryID")
        .SetIn32("hasCatogories", categoryIDs.Any() ? 1 : 0)
        .SetParameterList("categoryIDs", categoryIDs.Any() ? categoryIDs : new [] {"fake-non-existing-id"})
        .List<MyClassBE>();
}

تفسير:

  1. نقوم بتعديل الاستعلام لتجاهل الفئات عندما لا يكون ذلك متاحًا.
  2. نقوم بتعديل معلمة إضافية للإشارة (1).
  3. نضيف معرف عشوائي لا يستخدم أبدًا. فقط للتأكد من في بيان SQL صالح.

لذلك ، يمكنك الحفاظ على استعلامك المعقد وإضافة معلمات إضافية إليه.

عيب واضح هو أنه يمر معلمة غير ضرورية.

لكنه يفعل المهمة.

نصائح أخرى

أعتقد أنه يمكنك تجنب هذا الخطأ باستخدام .NET's Cast

return session.GetNamedQuery("MyClass_FilterByCategoryID")
    .SetParameterList("categoryIDs", categoryIDs)
    .List().Cast<MyClassBE>();

يجب أن يعيد قائمة فارغة ، وليس استثناء.

اختبر ما إذا كانت القائمة فارغة وافعل شيئًا آخر. في هذا الاستعلام بالذات ، تريد كل myclassbe غير الموجودين في معرفات الفئة مما يعني كل منهم:

public IList<MyClassBE> FilterByCategoryID(List<String> categoryIDs)
{
    if (categoryIDs.Count > 0)
        return session.GetNamedQuery("MyClass_FilterByCategoryID")
            .SetParameterList("categoryIDs", categoryIDs)
            .List<MyClassBE>();
    else
        return session.CreateQuery("from MyClassBe").List<MyClassBE>();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top