我正在处理一个案例,我通常在SQL中应该有一个'except'关键字。 此时我没有找到在NHibernate中完成此任务的解决方案。
这是一个有两个表的解决方案:用户表和FK表(包括用于在NH中轻松工作的PK)。 下面的SQL的含义是为某个用户尚未标记的用户提供记录。 所以,如果我们有3个用户:John,Jane en Jelain。 如果John没有标记任何人:给jane和jelain回复 如果John标记Jane:给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'
答案 0 :(得分:2)
我认为ICritearia没有例外,但您可以使用“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/
答案 1 :(得分:1)
好吧 - 我想你可以使用外连接将你的语句翻译成一个语句:
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));
在没有测试的情况下创建它总是很难 - 但我希望你能得到我的想法。
好吧 - 它看起来应该是左外连接 - 而不是右外连接
答案 2 :(得分:0)
我一直在检查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),并附上.future并过滤掉后者的第一个。
如果有人知道更好的解决方案。请告诉我。
也许除了以后进入NHibernate。我们会看到。我现在就给出自己的答案作为这个问题的答案。