【问题标题】:Using complex where clause in NHibernate mapping layer在 NHibernate 映射层中使用复杂的 where 子句
【发布时间】:2012-08-30 15:36:45
【问题描述】:

我之前在映射层中使用了 where 子句,以防止某些记录以可能的最低级别进入我的应用程序。 (主要是为了避免重写很多行代码来过滤掉不需要的记录)

这些都是简单的一列查询,就像这样

this.Where("Invisible = 0");

但是出现了需要使用exists sql 查询的场景。

exists (select ep_.Id from [Warehouse].[dbo].EventPart ep_ where Id = ep_.EventId and ep_.DataType = 4

在上述情况下,我通常会使用短名称引用父表 Event,即 event_.Id,但是由于 Nhibernate 会动态生成这些短名称,因此无法知道它将是什么。

所以我尝试只使用Id,从上面的ep_ where Id = ep_.EventId

当代码运行时,由于动态短名称,EventPart 表短名称ep_ 有另一个短名称前缀,event0_.ep_ 其中event0_ 指父表。

这会导致 SQL 错误,因为 .在event0_ep_ 之间

所以在我的EventMap 中,我有以下内容

this.Where("(exists (select ep_.Id from [isnapshot.Warehouse].[dbo].EventPart ep_ where Id = ep_.EventId and ep_.DataType = 4)");

但是当它生成时它会创建这个

select cast(count(*) as INT) as col_0_0_
from [isnapshot.Warehouse].[dbo].Event event0_
where (exists (select ep_.Id from [isnapshot.Warehouse].[dbo].EventPart event0_.ep_ where event0_.Id = ep_.EventId and ep_.DataType = 4)

它已正确地将event0_ 添加到Id

是否构建了映射层 where 子句来处理这个问题,如果是,我哪里出错了?

【问题讨论】:

  • 这是哪个 NHibernate 版本?
  • @Oskar 当前使用 3.3.1.4000

标签: c# sql nhibernate nhibernate-mapping


【解决方案1】:

尝试像这样在别名周围加上方括号:

exists (select ep_.Id from [Warehouse].[dbo].EventPart [ep_] where Id = ep_.EventId and ep_.DataType = 4

【讨论】:

  • 哇,这太简单了。
【解决方案2】:

在定义 ep_ 别名时尝试使用“as”关键字。

【讨论】:

  • 不幸的是同样的问题。它仍然将 event0_ 添加到开头。
【解决方案3】:

NHibernate.SqlCommand.Template 类有一个修改 Where 子句的方法 (RenderWhereStringTemplate)。查看代码,我认为问题在于它认为 ep_ 是一个标识符(基本上是映射类的一个属性),所以它用表的前缀作为前缀。确定它是否是标识符的代码非常简单 - 它基本上检查它是否被引用,或者它是否以 a-z 开头并且不包含。

我认为最简单的解决方案是将别名从 ep_ 更改为 _ep - 我通常使用 2 个 _ 来确保它不会与 NHibernate 生成的前缀冲突。

【讨论】:

    猜你喜欢
    • 2012-07-01
    • 1970-01-01
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    • 2010-11-21
    • 2014-11-12
    • 1970-01-01
    • 2011-02-25
    相关资源
    最近更新 更多