使用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!我不知道我是否正确表达了自己。无论如何,感谢您抽出时间阅读本文。
答案 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实体初始化,因此您可以立即使用它。