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的主要内容,如果未能解决你的问题,请参考以下文章
使用保持身份递增的 NHibernate 映射我现有的 ID 列
使用 NHibernate/Hibernate 将实体类型转换为子类型
查询时 NHibernate HasMany List 保持为空