使用nhibernate查询字节属性会导致无效的强制转换错误

本文关键字:无效 错误 转换 查询 nhibernate 字节 属性 使用 | 更新日期: 2023-09-27 18:00:44

nhibernate 3.1.0.4000在查询字节属性时有问题吗:

byte code = 2;
Group g = Repository<Group>.FindOne(p => p.Code == code);

异常文本:

Cause 'Specified cast is not valid.'
[InvalidCastException: Specified cast is not valid.]
   NHibernate.Type.ByteType.Set(IDbCommand cmd, Object value, Int32 index) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Type'ByteType.cs:44
   NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Type'NullableType.cs:180
...
[GenericADOException: could not execute query
[ select group0_.LabourLawGroupId as LabourLa1_235_, group0_.Code as Code235_ from personnel.LabourLawGroup group0_ where group0_.Code=? ]
  Name:p1 - Value:4
[SQL: select group0_.LabourLawGroupId as LabourLa1_235_, group0_.Code as Code235_ from personnel.LabourLawGroup group0_ where group0_.Code=?]]
   NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Loader'Loader.cs:1703
   NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Loader'Loader.cs:1601
   NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Loader'Loader.cs:1591
   NHibernate.Hql.Ast.ANTLR.Loader.QueryLoader.List(ISessionImplementor session, QueryParameters queryParameters) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Hql'Ast'ANTLR'Loader'QueryLoader.cs:300
   NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.List(ISessionImplementor session, QueryParameters queryParameters) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Hql'Ast'ANTLR'QueryTranslatorImpl.cs:108
   NHibernate.Engine.Query.HQLQueryPlan.PerformList(QueryParameters queryParameters, ISessionImplementor session, IList results) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Engine'Query'HQLQueryPlan.cs:78
   NHibernate.Impl.SessionImpl.List(IQueryExpression queryExpression, QueryParameters queryParameters, IList results) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Impl'SessionImpl.cs:645
   NHibernate.Impl.AbstractSessionImpl.List(IQueryExpression queryExpression, QueryParameters parameters) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Impl'AbstractSessionImpl.cs:92
   NHibernate.Impl.ExpressionQueryImpl.List() in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Impl'ExpressionQueryImpl.cs:60
   NHibernate.Linq.NhQueryProvider.ExecuteQuery(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Linq'NhQueryProvider.cs:79
   NHibernate.Linq.NhQueryProvider.Execute(Expression expression) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Linq'NhQueryProvider.cs:103
   System.Linq.Queryable.SingleOrDefault(IQueryable`1 source) +265
   Azarakhsh.Framework.Repository.NHibernateRepository`1.FindOne(Expression`1 expression) +223
   Azarakhsh.Framework.Repository.Repository`1.FindOne(Expression`1 expression) +100

使用nhibernate查询字节属性会导致无效的强制转换错误

我使用Linq2Nhibernate查询得到了相同版本的NHibernate的错误,如下所示:

var details =
    (from d in repository.AllEntities
        where (d.OtherTable.Field == someCriteria && d.LineIndex == 1)
        select d).ToList();

在这种情况下,LineIndex被映射为.NET Byte(不可为null)。我的堆栈跟踪顶部如下所示:

NHibernate.Type.ByteType.Set(IDbCommand cmd, Object value, Int32 index) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Type'ByteType.cs: line 44
NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd, Object value, Int32 index) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Type'NullableType.cs: line 180
NHibernate.Type.NullableType.NullSafeSet(IDbCommand st, Object value, Int32 index, ISessionImplementor session) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Type'NullableType.cs: line 139
NHibernate.Engine.QueryParameters.BindParameters(IDbCommand command, Int32 start, ISessionImplementor session) in d:'CSharp'NH'NH'nhibernate'src'NHibernate'Engine'QueryParameters.cs: line 630
...

从来源来看,Set方法如下所示:

public override void Set(IDbCommand cmd, object value, int index)
{
    ((IDataParameter) cmd.Parameters[index]).Value = (byte) value;
}

因此,它试图将一个对象强制转换为byte,并获得一个无效的强制转换。有趣的是,当我将文字1转换为byte时,我仍然会得到同样的错误。如果我使用const byte,也会发生这种情况。因此,我认为是更高层次的东西在拿byte,并用它做一些奇怪的事情

特别有趣的是,当字段不可为null时,它正在执行NullSafeSet。作为一个实验,我将LineIndex属性更改为int,但没有得到无效的强制转换异常。这似乎是NHibernate中的一个错误。我会试着把这个贴在NHibernate bug跟踪器上。

编辑

请注意,这个类似的错误NH-2485已作为非问题关闭。

其他类似/重叠错误:

  • NH-2789 LINQ查询字节?MSSQL 2005上的简单属性失败(tinyint)

我提交了这个错误:

  • NH-2812对非null字节属性执行Linq查询会引发InvalidCastException

编辑

3.3.1及以上版本解决了此问题。

只需使用short而不是byte

我今天在NHibernate 3.2.x中遇到了这个确切的问题。Scott Whitlock列出的错误在3.3.x中被标记为已修复,我可以确认升级NHibernat解决了这个问题。