带有 null child 的 Nhibernate 查询

Nhibernate query with null child

我需要检索所有具有有效 Wish 属性 的用户(因此不为空)。这是我的 class 的 xml:

<class name="Project.Engine.Domain.User,Project.Engine" table="Users" lazy="true">
  <id name="UserID" column="UserID">
    <generator class="native" />
  </id>
  <property name="Firstname" column="Firstname" type="string" not-null="true"
    length="255" />
  <property name="Lastname" column="Lastname" type="string" not-null="true"
    length="255" />
  <property name="Email" column="Email" type="string" not-null="true"
    length="255" />
  <one-to-one name="Wish" cascade="all" property-ref="UserID"
    class="Project.Engine.Domain.Wish, Project.Engine"  />
</class>

获取我所有用户的方法如下:

public PagedList<User> GetAll(int pageIndex, int pageSize,
    string orderBy, string orderByAscOrDesc)
{
    using (ISession session = NHibernateHelper.OpenSession())
    {
        var users = session.CreateCriteria(typeof(User));
        users.Add(Restrictions.IsNotNull("Wish"));
        return users.PagedList<User>(session, pageIndex, pageSize);
    }
}

如您所见,我在 child object 上添加了限制。这不能正常工作,因为方法 return 所有用户包括 Wish 属性 为 null 的用户。有帮助吗?

这是 child 的 xml:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="Project.Engine.Domain.Wish,Project.Engine" table="Wish" lazy="false">
    <id name="WishID" column="WishID">
      <generator class="native" />
    </id>
    <property name="UserID" column="UserID" type="int" not-null="true" length="32" />
    <property name="ContentText" column="ContentText" type="string" not-null="false" length="500" />
    <property name="Views" column="Views" type="int" not-null="true" length="32" />
    <property name="DateEntry" column="DateEntry" type="datetime" not-null="true" />
  </class>
</hibernate-mapping>   
使用 property-ref

one-to-one 映射不是 "actual" 一对一,通常这是应该使用 many-to-one 映射的标志。
也许这与你的麻烦无关,但你可以试一试。

"actual" 一对一具有从属 table 主键等于父 table 主键。 (在您的情况下,从属 table、Wish 将有一个外主键,在您的情况下为 UserId。请参阅此 example。)

我有一段时间 "played" 和 'one-to-one property-ref',但我总是因为很多问题而放弃。我用更经典的映射替换了它,或者更改我的数据库以获得实际的一对一,或者使用多对一并在子端使用集合,尽管它总是包含一个元素。

好吧,one-to-onenull 侧测试有一个错误,可能不存在。我已经遇到过但忘记了。 property-ref 只是让它诊断起来有点棘手,但它确实存在于实际 one-to-one 中。

这是它在 NHibernate 跟踪工具中对应的issue

解决方法:测试 Wish 的不可空 属性 的 null 状态,例如 Wish.Views.

请原谅我对测试语法的大胆猜测,多年来我不再使用 ,但通过示例尝试:

public PagedList<User> GetAll(int pageIndex, int pageSize,
    string orderBy, string orderByAscOrDesc)
{
    using (ISession session = NHibernateHelper.OpenSession())
    {
        var users = session.CreateCriteria(typeof(User));
        users.Add(Restrictions.IsNotNull("Wish.Views"));
        return users.PagedList<User>(session, pageIndex, pageSize);
    }
}

使用 ,我确认此解决方法适用于我自己的项目,示例如下:

// The "TotalAmount != null" seems to never be able to come false from a 
// .Net run-time view, but converted to SQL, yes it can, if TransactionRecord
// does not exist.
// Beware, we may try "o.TransactionsRecord != null", but you would get struck
// by https://nhibernate.jira.com/browse/NH-3117 bug.
return q.Where(o => o.TransactionsRecord.TotalAmount != null);

我保留我的另一个答案,因为您可能会考虑使用 many-to-one,特别是因为您没有进行双向映射(在 [=17 中没有相应的 constrained one-to-one =]) 除了没有实际的 one-to-onemany-to-one 没有这个错误。