Nhibernateで名前付きクエリを使用する場合、おそらく空のパラメーターリストを処理するにはどうすればよいですか?
-
02-10-2019 - |
質問
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:オブジェクト参照は、オブジェクトのインスタンスに設定されていません。
サーバースタックトレース:
at nhibernate.engine.typedValue..ctor(iTypeタイプ、オブジェクト値、エンティティモードエンティティモード)のc: junctions bs nhibernate.2.1.2.ga-src src nhibernate engine typedvalue.cs:line 25
nhibernate.impl.abstractqueryimpl.setParameterList(String name、Icollection Vals、iType Type)のC: Junctions bs 3rdparty nhibernate.2.1.2.ga-Src src nhibernate infr abstactqueryimpl.css:line 647
nhibernate.impl.abstractqueryimpl.setParameterList(String Name、Icollection Vals)のC: Junctions bs nhibernate.2.1.2.ga-Src src nhibernate Impl abstactryimpl.cs:line 666
myproject.dao.dao.dao.filterbycategoryid(list`1 categoryids)のmyclassdao.csで:50行目50行目
これを解決するための最良の方法は何でしょうか?指名されたクエリは、もちろん上記のクエリよりもはるかに複雑であるため、パラメーターリストを使用しない2番目のバージョンにコピーすることを避けたいと思います。
解決
私は同じ問題に直面したばかりなので、解決策を共有する必要がありますが、
クエリを次のように変更します。
<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).
- 使用されないランダムIDを追加します。確認するためだけに の SQLステートメントは有効です。
したがって、このようにして、複雑なクエリを保持し、追加のパラメーターを追加するだけです。
明らかな欠点は、不必要なパラメーターを通過することです。
しかし、それは仕事をします。
他のヒント
.netを使用して、そのエラーを回避できると思います Cast
return session.GetNamedQuery("MyClass_FilterByCategoryID")
.SetParameterList("categoryIDs", categoryIDs)
.List().Cast<MyClassBE>();
これは、例外ではなく、空のリストを返すはずです。
リストが空であるかどうかをテストし、何か他のことをします。この特定のクエリでは、カテゴリ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>();
}