NHibernate 查询参数解析器在 '/*[1]/@type' 表达式上抛出错误
Posted
技术标签:
【中文标题】NHibernate 查询参数解析器在 \'/*[1]/@type\' 表达式上抛出错误【英文标题】:NHibernate query parameter parser throws an error on '/*[1]/@type' expressionNHibernate 查询参数解析器在 '/*[1]/@type' 表达式上抛出错误 【发布时间】:2016-09-25 17:32:09 【问题描述】:我在数据库中有一个表,其中一列包含存储为 nvarchar 的 xml。我需要编写一个查询并根据存储在该列中的数据获取信息。
所以我最终使用 NHibernate 编写了以下本机 sql 查询:
string sql = @"SELECT a.id as s
FROM [DBT].[dbo].[tb_myTable] a
where (cast (a.vchExtendedInfo as XML)).value('/*[1]/@type','NVARCHAR(MAX)')='deal'"
ISQLQuery sqlQuery = HibernateUtil.GetCurrentSession().CreateSQLQuery(sql)
它会抛出一个错误:'ArgumentOutOfRangeException' - 长度不能小于零。参数名称:长度。
经过一些测试,我发现 NHibernate 正在尝试解析我的查询,而 '/*[1]/@type'
行可能是原因。 (这实际上是一个简化的示例,如果我删除它,所有其他条件都可以很好地工作)。
那么,我如何转义/修复我的查询以使其正常工作?
【问题讨论】:
【参考方案1】:我猜这是因为查询中的“@”。
您是否已经尝试过使用参数?
string sql = @"SELECT a.id as s
FROM [DBT].[dbo].[tb_myTable] a
where (cast (a.vchExtendedInfo as XML)).value(:type,'NVARCHAR(MAX)')=:value"
ISQLQuery sqlQuery = HibernateUtil.GetCurrentSession()
.CreateSQLQuery(sql)
.SetAnsiString("type", "/*[1]/@type")
.SetAnsiString("value", "deal");
【讨论】:
我在这个问题上花了很多时间。我最终遇到了一个错误,其中 xml.value 函数拒绝接受参数作为第一个值并且只接受字符串文字。我什至将 NHibernate 生成的代码复制到 SQL Studio 中,并试图让它在那里工作。最后一个半工作解决方案是我使用 sql.variable[] 通配符的地方,它没有给我错误,但查询产生了错误的结果(空查询)。 使用 NHibernate 的唯一可行的解决方案是创建一个动态 SQL 字符串并将其与 exec 命令一起传递给 sql。但是我们对重负载下的动态 SQL 性能有些担忧,所以最后我只是从 NHibernate 会话中剥离了底层连接,并按照我的同事的建议使用 ADO.NET 编写了我的语句。而且效果很好。以上是关于NHibernate 查询参数解析器在 '/*[1]/@type' 表达式上抛出错误的主要内容,如果未能解决你的问题,请参考以下文章
使用 NHibernate 作为带有输入参数的命名查询调用存储过程
Prisma 查询解析器失败:“where 选择器的参数无效”