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

Posted

技术标签:

【中文标题】NHibernate 保存非持久化实体,同时保持现有 ID【英文标题】:NHibernate save non-persisted entity while maintaining the existing ID 【发布时间】:2013-11-20 03:03:29 【问题描述】:

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

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

问题是实体地图用 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 生成策略,但能够以某种方式保留具有预定义 Id 的现有实体?

【问题讨论】:

如果你有两个数据库,你必须有两个SessionFactories 对吧? 不,它实际上是 1 个单独的应用程序和数据库,但通过数据库 A 和 B 分发给多个客户端> 【参考方案1】:

这里的逻辑很简单:

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

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

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

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

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

【讨论】:

你知道如何序列化实体来插入查询吗?确实是一个可行的方案

以上是关于NHibernate 保存非持久化实体,同时保持现有 ID的主要内容,如果未能解决你的问题,请参考以下文章

Fluent nHibernate 保存或更新派生实体

使用保持身份递增的 NHibernate 映射我现有的 ID 列

使用 NHibernate/Hibernate 将实体类型转换为子类型

查询时 NHibernate HasMany List 保持为空

通过 NHibernate 检索/保存链接到其他实体的日志条目的最佳方法是啥?

NHibernate 中的自引用实体给对象引用一个未保存的瞬态实例异常