我在处理一个情况下遇到问题,即发送到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 src src src nhibernate nhibernate nhibernate nhibernate prient typedvalue.cs:linepedvalue.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.1.2.ctor.ctor..ctor .. 25

在c: junctions bs bs 3rdparty nhibernate.2.1.2.ga-src src src src src src nhibernate nhibernate nhibernate nhibernate nhibernate nhibernate simpququereimpl.cs:lincequeryimpl.cc:

在c: junctions bs 3rdparty nhibernate.2.1.2.ga-src src src src src nhibernate nhibernate nhibernate nhibernate nhibernate nhibrnate nhibrnate nhibqueryimpl.cs:bs nhibernate.impl.impl.impl.stractqueryimpl.setParameterList(字符串名称,Icollection Vals)中

在myclassdao.cs中的myproject.dao.myclassdao.myclassdao.filterbycategoryid(list`1 categoryIds):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. 我们添加从未使用的随机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>();
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top