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 选择器的参数无效”

在 nhibernate 中使用参数值打印查询字符串?

Fluent NHibernate - NHibernate.QueryException:无法解析属性

Solr查询解析器大全

NHibernate 多次执行相同的查询