NHibernate在保持现有ID的同时保存非持久化实体

时间:2013-11-20 03:03:30

标签: c# mysql nhibernate orm fluent-nhibernate

这不是一个非常常见的情况,但在这个特殊的情况下,任务是完成这个:

  1. 序列化在数据库A中加载NHibernate的现有实体列表
  2. 将序列化实体导出到文件
  3. 使用NHibernate作为持久代理
  4. 将序列化实体文件导入数据库B.

    问题是实体地图用Id生成器标记:

    public class EntityMap
    {
        public EntityMap()
        {
            Id(x => x.Id)
                .GeneratedBy.Guid();
            // Other properties
        }
    }
    

    使用该映射,每次我打电话:

    ISession session = NHibernateSession.GetSession();
    IList<Entity> entities = // Load entity from serialized object in a file
    
    foreach(entity in entities)
    {
        session.Save(entity);
    }
    

    NHibernate不断为这些实体生成新的ID。

    有没有办法让映射具有Id生成策略,但能够以某种方式保留现有实体,并且预定义了它?

1 个答案:

答案 0 :(得分:1)

这里的逻辑很简单:

您希望拥有应用程序分配的标识符。因此,您应该为应用程序分配的标识符配置NHibernate。

你所要求的基本上是告诉NHibernate为你生成标识符,但无论如何都要坚持自己做。

还可以注意到NHibernate并不是真正的复制工具。您是否考虑将实体序列化为SQL脚本,您可以在目标数据库上轻松执行?这将绕过NHibernate的id分配。

对于分布式数据库,我的建议是: 首先,我将查看数据库系统本身是否具有可用于此目的的任何类型的复制/数据流/数据镜像。如果这不起作用,我可能会尝试编写类似的东西 - 也就是说,在读取端绕过NH,只需执行简单的表读取并将INSERT语句写入文件,收件人可以应用。只要不需要或很少需要数据转换,这就可以工作。如果数据需要复杂的转换(这是无法避免的)......好吧,如果逻辑变得足够复杂,我们就可以通过NH来做到这一点。

另一种方法是尝试捕获修改原始数据库的输入(例如命令模式),并将相同的输入也传递给所有其他数据库。基本上让每个系统对输入作出反应 - 使用确定性系统和相同的输入,所有数据库将最终处于相同的状态。