Criteria API With多对多关系中的子句

时间:2011-07-01 17:34:11

标签: nhibernate criteria criteria-api icriteria

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表。查询确实已发出,但数据库服务器当然会引发异常。

这是一个错误,不受支持还是我做错了?

2 个答案:

答案 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();