C# · 12月 25, 2021

c# – 使用nhibernate查询字节属性会导致无效的转换错误

查询字节属性的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,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,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解决方法 我使用Linq2Nhibernate查询使用相同版本的NHibernate得到相同的错误,如下所示: var details = (from d in repository.AllEntities where (d.OtherTable.Field == someCriteria && d.LineIndex == 1) select d).ToList();

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

NHibernate.Type.ByteType.Set(IDbCommand cmd,Int32 index) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Type\ByteType.cs: line 44NHibernate.Type.NullableType.NullSafeSet(IDbCommand cmd,Int32 index) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Type\NullableType.cs: line 180NHibernate.Type.NullableType.NullSafeSet(IDbCommand st,Int32 index,ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Type\NullableType.cs: line 139NHibernate.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;}

所以它试图将一个对象强制转换为一个字节并获得一个无效的强制转换.有趣的是,当我将文字1转换为一个字节时,我仍然得到相同的错误.如果我使用const字节也会发生这种情况.因此,我认为它是堆栈中更高的东西,它采用字节并用它做一些奇怪的事情.

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

编辑

请注意,this similar bug NH-2485已作为非问题关闭.

其他类似/重叠的错误:

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

我提交了这个bug:

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

编辑

3.3.1及更高版本解决了这个问题.