NHibernate 3 introduced the With clause用于Criteria API。我试图用它来限制多对多关系的连接,NHibernate将额外的连接限制应用于链接表而不是正确的表。
我在播放器和地址之间有多对多的关系,我希望通过限制Address.IsMailingAddress来返回播放器及其邮寄地址。限制where子句中的IsMailingAddress不返回没有邮寄地址(或根本没有地址)的记录,因此我需要在连接中限制它。下面的代码是简化的,我不能使用HQL。
查询:
var target = session.CreateCriteria<Player>()
.SetProjection(Projections.Property("PlayerId"))
.CreateAlias("Addresses", "ad", JoinType.LeftOuterJoin, Restrictions.Eq("ad.IsMailingAddress", true))
.Add(Restrictions.Eq("LastName", "Anonymous"))
.List();
生成SQL:
SELECT this_.PlayerId as y0_
FROM dbo.VPlayerExisting this_
left outer join dbo.LinkPlayAddr addresses3_
on this_.PlayerId = addresses3_.PlayerId
and (ad1_.MailingAddressFlag = 1 /* @p0 */)
left outer join dbo.VAddress ad1_
on addresses3_.AddressId = ad1_.AddressId
and (ad1_.MailingAddressFlag = 'Anonymous' /* @p1 */)
WHERE this_.Name_Last = @p2
MailingAddressFlag(映射到IsMailingAddress的列)在多对多链接表中受到限制,该表不存在,并且LastName限制在连接中应用于Address表。查询确实已发出,但数据库服务器当然会引发异常。
这是一个错误,不受支持还是我做错了?
答案 0 :(得分:1)
var target = session.CreateCriteria<Player>()
.CreateAlias("Addresses", "ad", JoinType.InnerJoin)
.Add(Restrictions.Eq("LastName", "Anonymous"))
.Add(Restrictions.Eq("ad.IsMailingAddress",true))
.List();
只是内部加入邮件地址并受到IsMailingAddress的限制?
应该将玩家(其中LastName是“匿名”)带回他们的MailingAddress,他们有一个地址,并且该地址被标记为IsMailingAddress。
答案 1 :(得分:0)
解决方案如下。应该只有一个地址设置了IsMailingAddress,因此如果有一个或没有使用内连接,则条件允许连接成功。
var target = session.CreateCriteria<Player>()
.SetProjection(Projections.Property("PlayerId"))
.CreateAlias("Addresses", "ad", JoinType.InnerJoin)
.Add(RestrictionsOr(Restrictions.Eq("ad.IsMailingAddress", true), Restrictions.IsNull("ad.AddressId")))
.Add(Restrictions.Eq("LastName", "Anonymous"))
.List();