我之前在映射层中使用了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子句来处理这个问题,如果是的话,我哪里出错?
答案 0 :(得分:1)
尝试在别名周围放置方括号,如下所示:
exists (select ep_.Id from [Warehouse].[dbo].EventPart [ep_] where Id = ep_.EventId and ep_.DataType = 4
答案 1 :(得分:0)
在定义ep_别名时尝试使用“as”关键字。
答案 2 :(得分:0)
NHibernate.SqlCommand.Template类有一个修改Where子句的方法(RenderWhereStringTemplate)。看一下代码,我认为问题在于它认为ep_是一个标识符(基本上是映射类的一个属性)所以它在前面加上表的前缀。确定它是否是标识符的代码非常简单 - 它基本上检查它是否被引用,或者它是否以a-z开头并且不包含。
我认为最简单的解决方案是将别名从ep_更改为_ep - 我通常使用2 _来确保它不会与NHibernate生成的前缀冲突。