如何';翻译';SQL';除了(N)休眠(标准API)

本文关键字:休眠 API 标准 除了 翻译 SQL 如何 | 更新日期: 2023-09-27 18:29:32

我正在处理一个案例,在SQL中,我通常应该有一个'except'关键字。此时此刻,我还没有找到在NHibernate实现这一目标的解决方案。

这是一个有两个表的解决方案:用户表和FK表(包括一个PK,以便在NH中轻松工作)。下面SQL的含义是为尚未被某个用户标记的用户提供所有记录。因此,如果我们有3个用户:John,Jane en Jelain。如果约翰不给任何人加标签:还简和杰兰如果约翰给简贴标签:还回杰兰如果约翰同时给简和杰兰贴标签:什么也不给。

SQL获取尚未标记的用户:

SELECT Id, DisplayName, Date, ProfilePicUrl
FROM MyDB.dbo.Users u
EXCEPT
SELECT u.Id, Displayname, Date, ProfilePicUrl
FROM MyDB.dbo.Users u
FULL OUTER JOIN MyDB.dbo.TaggedUsers t
ON u.Id=t.TargetId
WHERE
t.ShooterId = '1234' OR
u.Id = '1234'

如何';翻译';SQL';除了(N)休眠(标准API)

我认为ICritearia中没有EXCEPT,但您可以使用"Not in":

session.QueryOver(T).WhereRestrictionOn(t => t.SomeProperty).Not.IsIn(object[])

我认为这是一样的,看看:

http://blog.sqlauthority.com/2007/05/22/sql-server-2005-comparison-except-operator-vs-not-in/

好吧,我认为您可以使用外部联接将语句转换为语句:

select id, DisplayName, Date, ProfilePicUrl
from MyDB.dbo.Users u 
right outer join MyDB.dbo.TaggedUsers t on u.id = t.targetId
where t.ShooterId = '1234' or u.ID <> '1234' and t.ShooterId is null

这可以转化为一个标准声明,但我必须知道你的映射才能进行

.CreateAlias("TaggedUsers", "t", NHibernate.SqlCommand.JoinType.LeftOuterJoin)
.Add(Restrictions.IsNull("t.ShooterId")
.Add(Restrictions.Not(Restrictions.Eq("ID));

在没有测试的情况下创建这个总是很困难的,但我希望你能理解我的想法。

编辑

好吧,它看起来应该是左外部联接,而不是右外部联接

我一直在检查Anton和Bernhardrusch的两个答案,并尝试了一下。

当阅读一个答案时,我认为可以用左外部联接重写查询,并用NOT IN过滤掉记录。

这让我想到了这个代码:

SELECT *
FROM MyDB.dbo.Users u 
LEFT OUTER JOIN MyDB.dbo.TaggedUsers t ON u.Id=t.TargetId
WHERE t.ShooterId <> '6A17DC45-AB54-4534-B13B-A02001347664' 
  AND u.Id <> '6A17DC45-AB54-4534-B13B-A02001347664'
   OR t.ShooterId is null

使用Criteria API翻译了它,但遗憾的是,当使用多个用户时,此代码不起作用

此刻,我决定用代码而不是SQL来解决这个问题。

因此,我将做两个查询(选择所有用户和选择与用户id相对应的所有标记用户),并附上.efuture,然后用后者过滤掉第一个。

如果有人知道更好的解决方案。请告诉我。

也许只是以后再来NHibernate。我们拭目以待。现在我将给出我自己的答案作为这个问题的答案。