我正在使用NHibernate,需要检索和处理多达200万行。理想情况下,我可以处理每一行 - 一次一个 - 没有NHibernate同时加载所有200万内存(因为,你知道,这会伤害)。
我更希望得到一个IEnumerable,它会为每次读取迭代地调用数据读取器,这样我就可以处理读取的数据 - 然后丢弃它。通过这样做,我节省了大量的内存,并开始更快地处理结果。我还可以通过多线程和/或使用PLinq来提高性能。
这可能与NHibernate的ICriteria有关吗?它返回的所有内容似乎都是IList,并在关闭集合引用之前完全加载。为什么IList而不是IEnumerable?!
我并不是指NHibernate在加载子对象或父对象时使用的传统意义上的“懒惰”。我想要一个 lazy IEnumerable意味着从ICriteria对象获取IEnumerable 。 ICriteria只有一个List()方法,可以将结果加载到ArrayList中。
答案 0 :(得分:1)
ICriteria没有任何返回IEnumerable的方法,只有IQuery does。
答案 1 :(得分:0)
您要做的是将数据访问包装在如下方法中:
public IEnumerable<YourObject> GetALotOfRows() {
..execute DataReader
while(..read..) {
yield return yourObject;
}
}
现在没有VS或nHibernate方便,所以很抱歉半伪代码。但关键在于使用“收益率回报”。
答案 2 :(得分:0)
你必须逐行进行什么样的操作?我只是好奇:)。
您可以尝试分页结果 - 获得前10个,下一个10 ......依此类推。
修改强> 所以你会有
Session.CreateCriteria(typeof(T)).SetFirstResult(0).SetMaxResults(1).UniqueResult<T>();
Session.CreateCriteria(typeof(T)).SetFirstResult(1).SetMaxResults(1).UniqueResult<T>();
Session.CreateCriteria(typeof(T)).SetFirstResult(2).SetMaxResults(1).UniqueResult<T>();
你得到的照片,我想这不是最好的方式,它不是IEnumerable ......但它会起作用。你也可以做SetMaxResults(10)或更大的东西,所以不要一次发送1个。