我遇到的问题是处理发送到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>();
}
但是,当我将空List传递给方法时,我收到此错误:
System.NullReferenceException:未将对象引用设置为对象的实例。
服务器堆栈跟踪:
位于C:\ junctions \ BS \ 3rdParty \ NHibernate.2.1.2.GA-src \ src \ NHibernate \ Engine \ TypedValue中的NHibernate.Engine.TypedValue..ctor(IType类型,对象值,EntityMode entityMode)。 cs:第25行
在NHibernate.Impl.AbstractQueryImpl.SetParameterList(字符串名称,ICollection的瓦尔斯,ITYPE型)在C:\结\ BS \的3rdParty \ NHibernate.2.1.2.GA-SRC \ SRC \ NHibernate的\默认地将Impl \ AbstractQueryImpl.cs :第647行
在NHibernate.Impl.AbstractQueryImpl.SetParameterList(字符串名称,ICollection的瓦尔斯)在C:\结\ BS \的3rdParty \ NHibernate.2.1.2.GA-SRC \ SRC \ NHibernate的\默认地将Impl \ AbstractQueryImpl.cs:线666
在MyClassDao.cs中的MyProject.Dao.MyClassDao.FilterByCategoryID(List`1 categoryIDs):第50行
解决这个问题的最佳方法是什么?请注意,命名查询当然比上面提到的要复杂得多,所以我想避免将其复制到不使用参数列表的第二个版本。
答案 0 :(得分: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 :(得分:0)
我相信你可以通过使用.NET Cast
return session.GetNamedQuery("MyClass_FilterByCategoryID")
.SetParameterList("categoryIDs", categoryIDs)
.List().Cast<MyClassBE>();
来避免这个错误
那应该返回一个空列表,而不是例外。
答案 2 :(得分: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>();
}