2008-10-31 38 views
12

我有一个使用Firebird数据库作为数据存储(嵌入模式)的桌面(winforms)应用程序,并且我使用NHibernate作为ORM。我们需要支持的功能之一是能够将数据组导入/导出到外部文件。目前,这个外部文件也是一个与主数据库具有相同模式的数据库。使用NHibernate在多个数据库之间复制实体

我已经把NHibernate设置为查看多个数据库,我可以同时使用两个数据库。但是,问题是在两个数据库之间复制数据。我有两种复制策略:(1)复制对象的所有相同ID [又名导入/导出]和(2)复制大多数新ID [又名复制/复制]。我说“主要是新的”,因为有一些查找项目将始终使用相同的ID进行复制。

使用新ID复制所有内容都很好,因为我只需要一个“CopyForExport”方法,可以创建所有内容的副本并且不分配新ID(或清除对象树中的所有ID)。

什么是“最佳实践”方式来处理这种情况并在保留相同ID的情况下在数据库之间复制数据?我没有试图同步两个数据库,只是将一个子集(用户可选择的)或数据传输给其他人(然后将数据子集导入到他们自己的数据库中)。

进一步说明:我认为我已经将问题隔离为: 我想使用NHibernate的ISession.SaveOrUpdate功能,因此我使用未分配的身份生成器来设置我的实体。但是,我想要覆盖生成的标识(用于在同一进程中的多个数据库之间复制数据)时遇到问题。

有没有办法使用Guid.Comb或UUID生成器,但能够有时指定我自己的标识符(用于传输到具有相同模式的不同数据库连接)。

回答

13

我找到了我自己的问题的答案: 关键是ISession.Replicate方法。这使您可以在数据存储之间复制对象图并保留相同的标识符。要创建新的标识符,我想我可以使用ISession.Merge,但我仍然需要验证这一点。

虽然有一些注意事项:我的测试类有一个对父对象(多对一关系)的引用,并且我必须让该类非惰性加载才能使Replicate正常工作。如果我没有设置为急切加载(我猜是非延迟加载),它只会复制对象而不是父对象(我的hbm.xml文件中cascade =“all”)。

Java Hibernate文档有对Replicate()的引用,但NHibernate文档没有(在java文档中为section 10.9)。

这对复制行为很有意义,因为我们希望在将它们传送到另一个数据存储之前完全水化实体。但奇怪的是,即使两个会话都打开(每个数据存储都有一个会话),但当我想要复制对象时,它并没有想到会吸收对象。

+0

终于找到了这个解决方案,我遇到了类似的问题。我想这并没有帮助休眠站点目前停止运行。 – LizB 2009-04-30 05:57:18

0

您可以使用FBCopy。只需定义你想复制哪些表和列,然后我就可以完成这项工作。您也可以为每个表添加可选的WHERE子句,因此它只复制所需的行。

复制它时确保数据导出的顺序得到维护,以便外键不会中断。它也支持生成器。

相关问题