代码之家  ›  专栏  ›  技术社区  ›  Daniel Renshaw

如何在名为iquery参数的nhibernate上设置c_nullable value类型的值?

  •  31
  • Daniel Renshaw  · 技术社区  · 16 年前

    我正在使用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命名查询中,是否有任何方法可以为值类型的参数分配空值?

    3 回复  |  直到 12 年前
        1
  •  52
  •   Daniel Renshaw    16 年前

    好的,结果是在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);
            }
        }
    }
    
        2
  •  11
  •   Guillermo Gutiérrez    12 年前

    另一种方法是:

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

    等等…

    注意到 ? 使基元类型可以为空的符号。

        3
  •  3
  •   Rodolpho Brock    14 年前

    带链接的完整扩展方法(仅限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;
        }
    }