【发布时间】:2014-01-15 17:51:17
【问题描述】:
我的实体“TimeRecord”有一个集合“WayPoints”和两个一对一的属性“Location”和“WayData”。
每个属性都可以为空。
我需要为特定用户导出所有具有初始化属性的时间记录。
我实际上有一个可行的解决方案,但后来我开始使用NHibernateProiler,首先我注意到这段代码导致对数据库的查询数量荒谬。
var query = (from timeRecord in Session.Query<TimeRecord>()
.Where(tr => tr.User.Id == userid)
select timeRecord);
然后我将代码更改为:
var query = (from post in Session.Query<TimeRecord>()
.Fetch(x => x.Location)
.Fetch(x => x.WayData)
.FetchMany(x => x.WayPoints)
.Where(tr => tr.User.Id == userid)
select post);
这导致我遇到笛卡尔积问题。
现在我正在试验这段代码:
var sql1 = "from TimeRecord b left outer join fetch b.Location where b.User.Id=:User_id";
var sql2 = "from TimeRecord b left outer join fetch b.WayData where b.User.Id=:User_id";
var sql3 = "from TimeRecord b left inner join fetch b.WayPoints where b.User.Id=:User_id";
var result = Session.CreateMultiQuery()
.Add(Session.CreateQuery(sql1))
.Add(Session.CreateQuery(sql2))
.Add(Session.CreateQuery(sql3))
.SetParameter("User_id", userid)
.List();
但我不能说这是否是正确的方法,或者这是否可以通过 nHibernate 实现。有人可以帮我吗?
【问题讨论】:
-
笛卡尔积问题?查询是否产生重复的帖子,或者您的意思是它产生的 SQL 的结果集中有 #TimeRecords x #WayPoints?后者应该是正常的。尽管有
FetchMany,但我认为NHibernate 会返回不同的结果。 -
它的工作方式如下所述:nhforge.org/blogs/nhibernate/archive/2008/09/06/… -> 请注意,您有三个连接,一个内连接和两个外连接。 NHibernate 返回一组记录,其中包含所有三个连接的叉积。也就是说:如果一个博客有一个作者、10 个帖子和 100 个读者,那么结果集将有 1*10*100 = 1000 条记录。如果您有 100 个帖子和 1000 个读者,您将获得一组包含 100,000 条记录的集合!
-
重要的是:将返回多少条记录。我同意
Fetch(Many)会炸毁 SQL 结果集,但 AFAIK(我更多地使用实体框架)只会返回带有加载引用和集合的唯一帖子。当然,您可以寻找使其在引擎盖下更高效的方法,例如与期货:stackoverflow.com/a/5225939/861716. -
我同意 EF 会更好。我总是选错一个 :( 上次我使用它时,我有很多 N:N 关系,当时 EF 并没有真正支持,所以我决定下次使用 nHibernate 作为持久层。
-
不,EF 并不好。 NHibernate 批处理查询的能力非常独特。 EF 的
Include语句同样会破坏 SQL 结果集。
标签: linq nhibernate fluent-nhibernate linq-to-nhibernate nhibernate-criteria