带有 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-one
和 null
侧测试有一个错误,可能不存在。我已经遇到过但忘记了。 property-ref
只是让它诊断起来有点棘手,但它确实存在于实际 one-to-one
中。
这是它在 NHibernate 跟踪工具中对应的issue。
解决方法:测试 Wish
的不可空 属性 的 null
状态,例如 Wish.Views
.
请原谅我对测试语法的大胆猜测,多年来我不再使用 nhibernate-criteria,但通过示例尝试:
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);
}
}
使用 linq-to-nhibernate,我确认此解决方法适用于我自己的项目,示例如下:
// 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-one
。 many-to-one
没有这个错误。
我需要检索所有具有有效 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-one
和 null
侧测试有一个错误,可能不存在。我已经遇到过但忘记了。 property-ref
只是让它诊断起来有点棘手,但它确实存在于实际 one-to-one
中。
这是它在 NHibernate 跟踪工具中对应的issue。
解决方法:测试 Wish
的不可空 属性 的 null
状态,例如 Wish.Views
.
请原谅我对测试语法的大胆猜测,多年来我不再使用 nhibernate-criteria,但通过示例尝试:
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);
}
}
使用 linq-to-nhibernate,我确认此解决方法适用于我自己的项目,示例如下:
// 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-one
。 many-to-one
没有这个错误。