实体上的休眠预设ID,无法使其持续存在

Posted

技术标签:

【中文标题】实体上的休眠预设ID,无法使其持续存在【英文标题】:Nhibernate pre-set id on entity, can't get it to persist 【发布时间】:2013-03-24 22:42:57 【问题描述】:

我有一个实体Account,在正常情况下,它的 Guid Id 将由 NHibernate 生成。但是,我想“硬编码”一些Account Id,这些帐户将在任何地方引用并提供非常具体的功能。

我想在配置文件中定义这些对象,并附带一个预配置的 Guid Id,并在启动我的应用程序时检查这些帐户是否存在于数据库中。如果没有,我想按原样添加它们。如果它们在那里,我想覆盖数据库版本并保留配置文件中设置的属性。

我心想,这似乎是ISession.Merge 的用途,但对象并没有持久化。然后我想,这一定是ISession.Persist 的用途,但这会引发一个异常,抱怨坚持一个分离的对象。 ISession.SaveOrUpdate 同样不持久化对象。

我需要做什么才能在 NHibernate 中持久化这几个“预制”对象?

【问题讨论】:

听起来问题是有时您想自己生成 ID,而其他时候您希望 NH 生成 ID。我认为您需要创建一个自定义 IIdentifierGenerator,但我自己从未这样做过。 【参考方案1】:

您可以使用重载的 Save(object obj, object id); 保存具有特定 id 的实体; NHibernate ISession

/// <summary>
/// Persist the given transient instance, using the given identifier.
/// </summary>
/// <param name="obj">A transient instance of a persistent class</param>
/// <param name="id">An unused valid identifier</param>
void Save(object obj, object id);

【讨论】:

【参考方案2】:

将这些预定义的 Guid 放在字符串常量中。您可以从字符串常量创建 Guid 实例。在应用程序启动中使用这些 guid 查询数据库中的对象。如果找到更新对象并在数据库中进行更新。如果未找到,则使用预定义的 guid 创建对象实例并进行插入。

换句话说,这些“预制”对象并没有什么特别之处。将它们视为常规对象,就像没有预定义 Id 的任何其他对象一样。

更新:事情没那么简单。 NHibernate 可能会尝试使用新的 Guid 填写 ID,问题是如何告诉 NHibernate 有时您想自己执行此操作?

Session.Merge 将首先尝试从 Db 加载实体,如果找到,它将内存中的实例与 from-db 实例合并。否则它将向数据库添加新实例。

您始终可以使用 ADO.NET 直接添加此预定义实体,完全手动跳过 NH,但这不是一个很好的解决方案。

【讨论】:

听起来很简单,对吧?这基本上就是我所做的(减去常量字符串部分,但我认为这并不重要),但 NHibernate 不会坚持它们。【参考方案3】:

如果您的映射表明 NH 将生成 Id,那么您不能使用 NH 插入特定 Id。

要么使用临时 SqlQuery,要么创建部分修改的映射配置以用于具有 assigned Id 的初始化。

【讨论】:

以上是关于实体上的休眠预设ID,无法使其持续存在的主要内容,如果未能解决你的问题,请参考以下文章

unity检查预设上的中文

unity检查预设上的中文

CoreMIDI 制造商预设

当嵌入式键包含 SQL Server 上的标识列时,休眠插入失败

是否可以同时使用具有多个预设的 Jest?

模块构建失败:错误:检测到重复的插件/预设