【发布时间】:2012-04-04 23:14:13
【问题描述】:
我需要根据用户传入的一组日期将事件记录“批量”插入到数据库中。
我的事件实体有一个 StartTime 属性和一个 StopTime 属性。 Event 实体是我的应用程序中的核心实体,因此有许多与之关联的集合和实体引用。这是一个沉重的实体。
所以,我的原始代码让我遍历日期并执行以下操作:
Session.Save(new Event {StartTime=startdate, StopTime=endDate});
但是这并不能很好地扩展,我们在插入几百个日期时感受到了性能。
所以我想到了将所有日期插入临时表,但我不知道如何使用 HQL 来实现。
所以我的下一个想法是将所有日期作为子查询包含在内,这让我最接近。这是这种方法:
var hql = "INSERT INTO Event (Code, Comment, Description, Status, StartTime, StopTime)
SELECT ev.Code, ev.Comment, ev.Description, ev.Status, Dates.SDate, Dates.EDate
FROM Event ev,
(
SELECT '1/2/2012 3:00:00 PM' as SDate, '1/2/2012 6:00:00 PM' as EDate
UNION ALL SELECT '1/3/2012 3:00:00 PM', '1/3/2012 6:00:00 PM'
UNION ALL SELECT '1/4/2012 3:00:00 PM', '1/4/2012 6:00:00 PM'
) as Dates
WHERE ev.Id = :sourceEventId";
Session.CreateQuery(hql).SetInt32("sourceEventId", @event.Id).ExecuteUpdate();
但是 hql 失败,错误代码非常模糊。我在网上的研究告诉我,hql 还不支持 UNION 子句。
现在,我将这种方法重写为 SQL,并通过 Session.CreateSQLQuery() 执行,效果很好。但我不想将它作为 SQL 运行。无论如何,这违背了使用 NHibernate 的目的。
还有其他方法可以使用 HQL(或任何其他 NHibernate 技术)吗?
非常感谢这里的任何帮助!
更新
我忘了提到这是一个旧版 SQL Server 数据库(我在 sqlite 上运行单元测试),并且所有实体都使用 SQL 的 Identity 列生成它们的 ID。所以任何批处理的尝试都会失败。
正如我在下面的评论中所解释的,我还尝试了无状态会话方法。 NHibernate 将无法告诉我我需要先保存所有延迟加载的实体。我通过删除这些映射暂时解决了这个问题,它确实有效,而且比常规会话更快。但我最终还是不得不一次插入每个实体。
【问题讨论】:
标签: c# .net nhibernate hql bulkinsert