在nHibernate中过滤没有连接的子节点

时间:2009-07-15 11:01:45

标签: c# nhibernate

使用nHibernate尝试以下操作时遇到问题:

  • 急切加载。
  • 使用选择(这是我的问题,我只能使用联接来执行此操作)
  • 过滤儿童。

让我们使用一个例子,我们有RichPerson类可以有多个:汽车,房屋,摩托车和公司。全部映射到具有不同表的不同实体。

如果我尝试以下方法:

session.CreateCriteria(typeof (RichPerson))
    .Add(Expression.Eq("Id", someId))
    .CreateCriteria("Cars")
    .Add(Expression.Eq("Brand","Ferrari")

nHibernate将进行内部联接以检索汽车。如果RichPerson 某些法拉利汽车,则联接将发送重复数据。

即使有.SetFetchMode("Cars",FetchMode.Select) nHibernate也会加入。

我想这次加入是因为我问:有身份X的富人和法拉利车。因此,需要连接。但我只想预装(不知何故)法拉利赛车。并将它们用作guy.Cars

UF!我不知道我是否正确表达了自己。无论如何,感谢您抽出时间阅读本文。

3 个答案:

答案 0 :(得分:0)

您必须执行联接以测试相关表中的条件。没有办法解决这个问题。您要做的还是在相关表中预加载数据,立即实例化这些对象。

session.CreateCriteria(typeof (RichPerson))
    .Add(Expression.Eq("Id", someId))
    .SetFetchMode("Cars", FetchMode.Join)
    .CreateCriteria("Cars")
    .Add(Expression.Eq("Brand","Ferrari");

这也可以通过HQL来完成,如:

"SELECT p FROM RichPerson p inner join fetch p.cars c where p.id=:id and c.brand=:brand"

答案 1 :(得分:0)

您是说RichPerson的映射具有Cars属性,其FK为Brand,对吧?如果是,那就是<many-to-one>而不是你很好,你可以这样做,只是跳过CreateCriteria的使用,你会没事的,因为Brand字段在{ {1}}表。

但是如果它是RichPerson,这对我来说就是这样,那么你必须进行加入,因为<one-to-many>字段没有存储在Brand中表,但在RichPerson表中,该表引用回Cars(或任何您称之为)字段中的RichPerson.Id字段。

如果这没有意义,请发布映射文件,我们可以为您确认正确的方法。

答案 2 :(得分:0)

  

我只想预先加载(一些如何)   法拉利汽车。并将它们用作   guy.Cars

听起来你这里有一个懒惰的初始化问题。

这是一篇有趣的帖子:

http://nhforge.org/wikis/howtonh/lazy-loading-eager-loading.aspx

简而言之,您的查询看起来很好。但是在您的查询之后(当会话仍然打开时),请尝试添加:

NHibernateUtil.Initialize(guy.Cars);

这将强制您的Cars实体初始化,因此您可以立即使用它。

相关问题