说我有这些查询如何在nhibernate中使用ToFuture?
// Linq
var allRecords = session.Query<Table1P>().FetchMany(x => x.Table2).FetchMany(x => x.Table3).FetchMany(x => x.Table4).FetchMany(x => x.Table6).ToList();
// Hql
string hqlQuery = @"from Table1 tbl1
left join fetch tbl1.Table2 tbl2
left join fetch tbl1.Table3
left join fetch tbl1.Table4
left join fetch tbl1.Table6
left join fetch tbl2.Table5s";
在上述情况下,我需要做的所有这些连接停止延迟加载,并做预先加载。现在这会在nhibernate分析器中产生一个关于太多连接的警报。
http://nhprof.com/Learn/Alerts/TooManyJoins
所以一个方法来阻止这种警告是分手的连接。并做多个查询。这是我想要做的。然而,与此同时,我一直在阅读关于未来的特性,我认为这将允许我分解查询(阻止太多连接),但仍然一次执行它。
编辑
我一直在努力ToFuture并试图限制数据量要回来的时候发现它比较慢(如果我试图让一切恢复那么快,因为它不会崩溃) 。
var allRecords = session.Query<Table1P>().FetchMany(x => x.Table2).FetchMany(x => x.Table3).FetchMany(x => x.Table4).FetchMany(x => x.Table6).Take(3000).ToList();
// result (2.731 seconds), row count 3000, duration 8 ms/ 2013 ms
select TOP (3000 /* @p0 */) table1p0_.Id as Id1_0_,
table2x1_.Id as Id2_1_,
table3x2_.Id as Id3_2_,
table4x3_.Id as Id4_3_,
table6x4_.Id as Id6_4_,
table1p0_.F1 as F2_1_0_,
table1p0_.F2 as F3_1_0_,
table1p0_.F3 as F4_1_0_,
table2x1_.F1 as F2_2_1_,
table2x1_.F2 as F3_2_1_,
table2x1_.F3 as F4_2_1_,
table2x1_.Table1_id as Table5_2_1_,
table2x1_.Table1_id as Table5_0__,
table2x1_.Id as Id0__,
table3x2_.F1 as F2_3_2_,
table3x2_.F2 as F3_3_2_,
table3x2_.F3 as F4_3_2_,
table3x2_.Table1_id as Table5_3_2_,
table3x2_.Table1_id as Table5_1__,
table3x2_.Id as Id1__,
table4x3_.F1 as F2_4_3_,
table4x3_.F2 as F3_4_3_,
table4x3_.F3 as F4_4_3_,
table4x3_.Table1_id as Table5_4_3_,
table4x3_.Table1_id as Table5_2__,
table4x3_.Id as Id2__,
table6x4_.F1 as F2_6_4_,
table6x4_.F2 as F3_6_4_,
table6x4_.F3 as F4_6_4_,
table6x4_.Table1_id as Table5_6_4_,
table6x4_.Table1_id as Table5_3__,
table6x4_.Id as Id3__
from Table1 table1p0_
left outer join [Table2] table2x1_
on table1p0_.Id = table2x1_.Table1_id
left outer join [Table3] table3x2_
on table1p0_.Id = table3x2_.Table1_id
left outer join [Table4] table4x3_
on table1p0_.Id = table4x3_.Table1_id
left outer join [Table6] table6x4_
on table1p0_.Id = table6x4_.Table1_id
使用ToFuture
// result (4.808 seconds), row count 6944/75/ 374, duration 1ms/4022 ms
// will load the Entities with Table2 fetched
var allRecords = session.Query<Table1P>()
.FetchMany(x => x.Table2)
.ToFuture()
.Take(3000);
// will load the Entities with Table3 fetched
session.Query<Table1P>()
.FetchMany(x => x.Table3)
.ToFuture();
// will load the Entities with Table4 fetched
session.Query<Table1P>()
.FetchMany(x => x.Table4)
.ToFuture();
// will load the Entities with Table6 fetched
session.Query<Table1P>()
.FetchMany(x => x.Table6)
.ToFuture();
// will trigger all queries at once and the session cache will make sure,
// that the results of all queries fill the same Entities
allRecords.ToList();
select table1p0_.Id as Id1_0_,
table2x1_.Id as Id2_1_,
table1p0_.F1 as F2_1_0_,
table1p0_.F2 as F3_1_0_,
table1p0_.F3 as F4_1_0_,
table2x1_.F1 as F2_2_1_,
table2x1_.F2 as F3_2_1_,
table2x1_.F3 as F4_2_1_,
table2x1_.Table1_id as Table5_2_1_,
table2x1_.Table1_id as Table5_0__,
table2x1_.Id as Id0__
from Table1 table1p0_
left outer join [Table2] table2x1_
on table1p0_.Id = table2x1_.Table1_id;
select table1p0_.Id as Id1_0_,
table3x1_.Id as Id3_1_,
table1p0_.F1 as F2_1_0_,
table1p0_.F2 as F3_1_0_,
table1p0_.F3 as F4_1_0_,
table3x1_.F1 as F2_3_1_,
table3x1_.F2 as F3_3_1_,
table3x1_.F3 as F4_3_1_,
table3x1_.Table1_id as Table5_3_1_,
table3x1_.Table1_id as Table5_0__,
table3x1_.Id as Id0__
from Table1 table1p0_
left outer join [Table3] table3x1_
on table1p0_.Id = table3x1_.Table1_id;
select table1p0_.Id as Id1_0_,
table4x1_.Id as Id4_1_,
table1p0_.F1 as F2_1_0_,
table1p0_.F2 as F3_1_0_,
table1p0_.F3 as F4_1_0_,
table4x1_.F1 as F2_4_1_,
table4x1_.F2 as F3_4_1_,
table4x1_.F3 as F4_4_1_,
table4x1_.Table1_id as Table5_4_1_,
table4x1_.Table1_id as Table5_0__,
table4x1_.Id as Id0__
from Table1 table1p0_
left outer join [Table4] table4x1_
on table1p0_.Id = table4x1_.Table1_id;
select table1p0_.Id as Id1_0_,
table6x1_.Id as Id6_1_,
table1p0_.F1 as F2_1_0_,
table1p0_.F2 as F3_1_0_,
table1p0_.F3 as F4_1_0_,
table6x1_.F1 as F2_6_1_,
table6x1_.F2 as F3_6_1_,
table6x1_.F3 as F4_6_1_,
table6x1_.Table1_id as Table5_6_1_,
table6x1_.Table1_id as Table5_0__,
table6x1_.Id as Id0__
from Table1 table1p0_
left outer join [Table6] table6x1_
on table1p0_.Id = table6x1_.Table1_id;
查询和时间从NHibernate的探查取。测试是通过运行一组代码,记录结果,停止.net开发服务器,然后运行另一组代码来运行的。
表1 - 6200行 表2 - 744行 表3 - 75行 表4 - 374行 表6 - 300行
差不多表1具有一对多的所有其他表。
你的'.Take(3000)'应该放在'.ToFuture()'之前,如果你想将它作为'TOP(3000)' –
啊应用到查询中。好吧现在我得到了3021/3998/374/300的行数。持续时间35ms/4825共5.703秒。在一举之中,我可以获得3000行,持续时间为2ms/2307毫秒,总共为3.33。似乎ToFuture()需要返回更多的行才能获得相同的数量并且速度较慢。不知道这是如何,或者如果我仍然做错了什么。 – chobo2