【问题标题】:Can I use an assigned, natural-key identifier while still allowing NHibernate to identify transient instances?我可以使用分配的自然键标识符,同时仍然允许 NHibernate 识别瞬态实例吗?
【发布时间】:2010-06-23 17:24:07
【问题描述】:

对象A 具有一对多关联:许多对象B

当我查看数据库时 -- TableB -- 我希望看到唯一、可读的字符串 A.Name,而不是总是在代理整数标识符上加入或子选择来查看名称。

我可以将Name 映射为A 的标识符,但这会导致大量额外的SELECT 查询,因为NHibernate 无法识别A 的实例是暂时的还是持久的。

我想我可以使用复合键,将本地分配的代理键与自然键结合起来。这似乎不是最理想的,但我很想听听一些意见。

我真正需要的是一种使用单列自然键同时允许 NHibernate 识别瞬态实例的策略。

  • 有可能吗?
  • 什么是映射——fluent 还是 hbm?

另一方面,如果这是一个糟糕的想法,我应该只依赖带有子选择的数据库视图,请解释一下。

谢谢。

【问题讨论】:

    标签: c# .net nhibernate surrogate-key natural-key


    【解决方案1】:

    这是一个糟糕的想法,当您需要“查看数据库”时,您应该创建一个执行连接的视图。

    这是一个糟糕的主意,因为 Name 不是表 A 的主键。

    但我认为,如果您对 A.Name 施加唯一约束并将其映射为标识符,您就可以做到这一点。我不确定 NHibernate 对于未保存的值是否默认为 null 或空字符串,但您可以使用

    Id(x => x.Name).GeneratedBy.Assigned().UnsavedValue(string.Empty); // or null
    

    如果你使用 string.Empty 而不是 A 的构造函数必须将 Name 初始化为 string.Empty。我还会从 A 中删除代理标识符,也可能是表本身,因为它没有任何作用。

    【讨论】:

    • 对不起,简短的回答,我已经扩展了。
    • 感谢您的更新。使用UnsavedValue() 的问题是我永远无法持久化它——一旦我指定了一个名称,NHibernate 就会将它视为已保存,不是吗?
    • 我没有使用分配的 ID,但我认为工作流程是创建对象,在其上调用 ISession.Save(),设置 ID,然后刷新会话。 NH 将发出插入然后更新;缺点是 ID 必须可以为空才能插入成功。您也可以使用版本字段,请参阅stackoverflow.com/questions/1070311/…
    猜你喜欢
    • 2022-01-08
    • 2010-12-18
    • 2020-12-27
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多