如何使用 NHibernate 迭代整个表?
Posted
技术标签:
【中文标题】如何使用 NHibernate 迭代整个表?【英文标题】:How to iterate on an entire table using NHibernate? 【发布时间】:2011-03-29 13:45:00 【问题描述】:我正在寻找一个简单的 NHibernate 示例,它将向我展示如何在整个表上进行迭代。这是我到目前为止所拥有的,但它不起作用。我收到“System.InvalidOperationException:由于对象的当前状态,操作无效。”。我做错了什么?
public IEnumerable<EMPDATA> getEMPData()
using (ISession session = NHibernateHelper.OpenSession())
IEnumerable<EMPDATA> empData = session.CreateQuery("from EMPDATA").Enumerable<EMPDATA>();
return empData;
public static void Main(System.String[] args)
log.Debug("Entered main");
Console.WriteLine("Entered main");
try
IEMPDataRepository repository = new EMPDataRepository();
IEnumerable<EMPDATA> iterList = repository.getEMPData();
while( iterList.GetEnumerator().MoveNext())
EMPDATA emp = iterList.GetEnumerator().Current;
log.Debug(emp.EMP_ID);
catch (System.Exception ex)
log.Error("Exception occured reading emp data", ex);
这是我的映射:
【问题讨论】:
为什么需要遍历整个表? 我需要遍历整个表,因为我正在将此表中的记录与另一个表进行比较,如果有多余的行,我想将它们插入到另一个表中。 在我看来,NHibernate 并不是真正适合批处理操作的工具 - 最佳解决方案取决于您需要这样做的原因。 那么您应该在数据库级别执行此操作,而不是将它们全部放入内存并尝试实现相同的目标。只需使用游标编写存储过程。它的性能比在表上执行 SELECT+N 好 10 倍。 我同意它不是批处理操作的正确工具。但是有办法吗?我只是不想将这些记录保存在内存中,这就是我尝试迭代它们的原因。 【参考方案1】:您请求一个 Enumerable 结果,这可能依赖于会话仍处于打开状态。
由于您在返回 Enumerable 实例后 Dispose 会话,因此您已经关闭了与数据库的连接。
编辑:见NotSupportedException on IQuery's Enumerable when using statelesssession
【讨论】:
实际上查看 NHibernate 代码,Enumerable 在调用时执行查询。否则他会得到一个已处理的会话异常。 如果你想用 NHibernate 枚举大量数据,使用无状态会话以避免将所有读取实体存储在一级缓存中也是有意义的。 执行查询和遍历结果集是两件不同的事情,但你可能是对的,我没看过。 谢谢,我会看看会话是否正在关闭,我没有明确关闭连接。 关闭会话也会强制关闭数据库访问【参考方案2】:简答:使用.List
而不是.Enumerable
。
【讨论】:
【参考方案3】:更长的答案: 1. 我同意 Phill - 看起来像是一份 SP 的工作 2. Diego (显然)是对的,但如果我是你,我会使用 SetFirstResult() 和 SetMaxResult() 来控制每次迭代中加载到内存中的数据量(不要忘记在当然,使用这种方法)。
【讨论】:
以上是关于如何使用 NHibernate 迭代整个表?的主要内容,如果未能解决你的问题,请参考以下文章
Fluent NHibernate:如何将整个类映射为只读?
NHibernate 2 + NHibernate.JetDriver + MS Access:如何访问表的“附件”字段