4

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 : オブジェクト参照がオブジェクトのインスタンスに設定されていません。

サーバー スタック トレース:

C:\junctions\BS\3rdParty\NHibernate.2.1.2.GA-src\src\NHibernate\Engine\TypedValue.cs の NHibernate.Engine.TypedValue..ctor(IType タイプ、オブジェクト値、EntityMode entityMode) で: 行25

C:\junctions\BS\3rdParty\NHibernate.2.1.2.GA-src\src\NHibernate\Impl\AbstractQueryImpl.cs の NHibernate.Impl.AbstractQueryImpl.SetParameterList(String name, ICollection vals, IType type): 647 行目

C:\junctions\BS\3rdParty\NHibernate.2.1.2.GA-src\src\NHibernate\Impl\AbstractQueryImpl.cs の NHibernate.Impl.AbstractQueryImpl.SetParameterList(String name, ICollection vals): 666 行目

MyClassDao.cs の MyProject.Dao.MyClassDao.FilterByCategoryID(List`1 categoryIDs): 50 行目

これを解決する最善の方法は何ですか?もちろん、名前付きクエリは上記のものよりもはるかに複雑であるため、パラメーター リストを使用しない 2 番目のバージョンにコピーすることは避けたいと思います。

4

3 に答える 3

3

私はちょうど同じ問題に直面したので、解決策を共有する必要があります:

クエリを次のように変更します。

<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. 使用されていないランダムな ID を追加します。IN SQL ステートメントが有効であることを確認するだけです。

このようにして、複雑なクエリを保持し、追加のパラメーターを追加するだけで済みます。

明らかな欠点は、不要なパラメーターを渡すことです。

しかし、それは仕事をします。

于 2011-02-22T01:15:48.713 に答える
0

.NETを使用することでそのエラーを回避できると思いますCast

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

これにより、例外ではなく、空のリストが返されます。

于 2010-09-13T13:05:23.567 に答える
0

リストが空かどうかをテストし、別のことを行います。この特定のクエリでは、カテゴリ ID にないすべての 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>();
}
于 2010-09-13T13:19:56.710 に答える