如何C#可空类型的值可以在NHibernate的命名IQUERY参数设置?(How can C# n

2019-07-29 03:40发布

我使用NHibernate和调用通过命名查询的存储过程:

<sql-query name="SearchStuff" read-only="true" cacheable="true">
  <return class="ResultEntity" />
  EXEC [SearchStuff] ?, ?, ?    </sql-query>

许多存储过程的参数是故意为空的 - 这不能改变。

在C#:

IQuery listQuery = this.Session.GetNamedQuery("SearchStuff");
listQuery.SetInt32(0, param1);
listQuery.SetDateTime(1, param2);
listQuery.SetString(2, param3);
IList<ResultEntity> results = listQuery.List<ResultEntity>();

不幸的是,NHibernate的不提供任何SetXyz()为空的值类型的方法,所以我尝试添加一些扩展方法来补偿:

public static class QueryExtensions
{
    public static void SetInt32(this IQuery query, int position, int? val)
    {
        if (val.HasValue)
        {
            query.SetInt32(position, val.Value);
        }
        else
        {
            query.SetParameter(position, null);
        }
    }

    public static void SetInt32(this IQuery query, string name, int? val)
    {
        if (val.HasValue)
        {
            query.SetInt32(name, val.Value);
        }
        else
        {
            query.SetParameter(name, null);
        }
    }

    public static void SetDateTime(this IQuery query, int position, DateTime? val)
    {
        if (val.HasValue)
        {
            query.SetDateTime(position, val.Value);
        }
        else
        {
            query.SetParameter(position, null);
        }
    }

    public static void SetDateTime(this IQuery query, string name, DateTime? val)
    {
        if (val.HasValue)
        {
            query.SetDateTime(name, val.Value);
        }
        else
        {
            query.SetParameter(name, null);
        }
    }
}

我已经试过各种版本的这些,但没有工作。 上面的代码失败,错误:

System.ArgumentNullException : A type specific Set(position, val) should be called because the Type can not be guessed from a null value.

我也试过根本就没有设置参数,但NHibernate的需要设置各项参数。 我同时使用位置和命名的版本相同的结果尝试。

有没有什么办法,以空值分配到NHibernate的命名查询值类型参数?

Answer 1:

OK,原来有上的setParameter一些覆盖允许类型进行​​明确设置。 例如:

query.SetParameter(position, null, NHibernateUtil.Int32);

完整的扩展方法(的Int32只有DATETIME)现在是:

public static class QueryExtensions
{
    public static void SetInt32(this IQuery query, int position, int? val)
    {
        if (val.HasValue)
        {
            query.SetInt32(position, val.Value);
        }
        else
        {
            query.SetParameter(position, null, NHibernateUtil.Int32);
        }
    }

    public static void SetInt32(this IQuery query, string name, int? val)
    {
        if (val.HasValue)
        {
            query.SetInt32(name, val.Value);
        }
        else
        {
            query.SetParameter(name, null, NHibernateUtil.Int32);
        }
    }

    public static void SetDateTime(this IQuery query, int position, DateTime? val)
    {
        if (val.HasValue)
        {
            query.SetDateTime(position, val.Value);
        }
        else
        {
            query.SetParameter(position, null, NHibernateUtil.DateTime);
        }
    }

    public static void SetDateTime(this IQuery query, string name, DateTime? val)
    {
        if (val.HasValue)
        {
            query.SetDateTime(name, val.Value);
        }
        else
        {
            query.SetParameter(name, null, NHibernateUtil.DateTime);
        }
    }
}


Answer 2:

完成它的另一种方法是:

query.SetParameter<int?>(0, null);
query.SetParameter<DateTime?>(1, null);
...

等等...

注意? 符号,使原语类型可为空的。



Answer 3:

完整的扩展方法(只的Int32和DateTime)与链接现在是:

public static class QueryExtensions
{
    public static IQuery SetInt32(this IQuery __query, int __position, int? __val)
    {
        var _query = __val.HasValue ? __query.SetInt32(__position, __val.Value) : __query.SetParameter(__position, null, NHibernateUtil.Int32);

        return _query;
    }

    public static IQuery SetInt32(this IQuery __query, string __name, int? __val)
    {
        var _query = __val.HasValue ? __query.SetInt32(__name, __val.Value) : __query.SetParameter(__name, null, NHibernateUtil.Int32);

        return _query;
    }

    public static IQuery SetDateTime(this IQuery __query, int __position, DateTime? __val)
    {
        var _query = __val.HasValue ? __query.SetDateTime(__position, __val.Value) : __query.SetParameter(__position, null, NHibernateUtil.DateTime);

        return _query;
    }

    public static IQuery SetDateTime(this IQuery __query, string __name, DateTime? __val)
    {
        var _query = __val.HasValue ? __query.SetDateTime(__name, __val.Value) : __query.SetParameter(__name, null, NHibernateUtil.DateTime);

        return _query;
    }
}


文章来源: How can C# nullable value typed values be set on NHibernate named IQuery parameters?