我正在编写一个应用程序,需要定期(例如每周)循环数据库中的数百万条记录,并对每行的结果执行代码。
由于表格太大,我怀疑当我调用SomeObject.FindAll()时,它会读取所有140万行,并尝试返回SomeObject []中的所有行。
有没有办法可以执行SomeObject.FindAll()表达式,但是以更加DBMS友好的方式加载值?
答案 0 :(得分:0)
不是FindAll()
- 正如你所推测的那样,它会一次尝试加载指定类型的所有实例(并且,根据你如何设置NHibernate可能会发出一个惊人的结果要执行此操作的SQL查询数。)
延迟加载仅适用于对象的属性,因此,例如,如果您有一个持久化类型SomeObjectContainer
,该类型具有SomeObject
列表SomeObject
,其映射方式应匹配所有{ {1}}和lazy="true"
,然后在该列表属性上执行foreach
,您就可以获得所需内容,排序等级;默认情况下,NHibernate会为列表中的每个元素发出一个查询,一次只加载一个元素。当然,读缓存会变得很大,所以你可能需要冲洗很多。
您可以执行的是发出HQL(甚至是嵌入式SQL)查询以检索所有SomeObject的所有ID,然后一次一个地使用FindByPrimaryKey获取相关对象。再一次,它并不是特别优雅。
老实说,在这样的情况下,我可能会把它变成存储过程中的计划维护工作 - 除非你真的必须在对象上运行代码而不是操纵数据不知何故。它可能会惹恼对象纯粹主义者,但有时候存储过程是正确的方法,特别是在这种批处理作业场景中。