进一步优化NHibernate CreateMultiQuery用于急切提取

时间:2010-10-05 07:52:05

标签: nhibernate optimization

当我们想要通过单个往返来急切地加载实体及其子实体时,建议使用CreateMultiQuery - 返回更少的列,因为我们没有X * Y * Z * T而是X,X * Y,X * Z,X * T。这对我来说效果很好,但它并不是最佳的,因为X是一个包含许多列的表,我从数据库中提取了大量数据。例如:

const string query1 =“select f from Feature f where f.Id in(:fids)”; const string query2 =“select f from Feature f left join fetch f.SprintAssignment where f.Id in(:fids)”; const string query3 =“select f from Feature f left join fetch f.Tasks where f.Id in(:fids)”; const string query4 =“select f from Feature f left join fetch f.Tags where f.Id in(:fids)”; const string query5 =“select f from Feature f inner join fetch f.Project where f.Id in(:fids)”;

现在,功能表非常大(大约20个字段,包括其他表的FK)。这意味着对于query2-5,我得到了大量的数据复制(整个要素字段+连接表字段)。

显然,我们需要FeatureId,因此Identity Map可以解析所有内容(整个Feature对象及其所有子实体),但为什么要拉掉其余的呢?

有没有办法对其进行优化,以便只返回FeatureId +连接表列?

2 个答案:

答案 0 :(得分:0)

不,没有

答案 1 :(得分:0)

您必须在查询中使用Projection,并根据id投影查询已连接的表格。这样您只能获取已连接表的列。这里是一个使用vb.net中Criteria的小样本

' create the first query, and restrict it to ids
Dim dFilterTask As NHibernate.Criterion.DetachedCriteria = Nothing
dFilterTask = NHibernate.Criterion.DetachedCriteria.For(GetType(Task))
' add your criterias here
dFilterTask.Add(your criterias here)
dFilterTask.SetProjection(NHibernate.Criterion.Projections.Id)

' second query, select where the task id is in your first query
Dim dFilterTaskJoin As NHibernate.Criterion.DetachedCriteria = Nothing
dFilterTaskJoin = NHibernate.Criterion.DetachedCriteria.For(GetType(TaskJoinedClass))
dFilterTaskJoin.Add(NHibernate.Criterion.Subqueries.PropertyIn("TaskId", dFilterTask))