有没有办法为 n-hibernate 映射定义可重用属性?

Posted

技术标签:

【中文标题】有没有办法为 n-hibernate 映射定义可重用属性?【英文标题】:Is there a way to define reusable properties to n-hibernate mappings? 【发布时间】:2009-11-04 08:44:10 【问题描述】:

我有一个场景,我想向我的实体添加一些标准属性。这意味着我将拥有例如1 个 int 和 2 个 string 属性应用于所有相关实体。我有超过 100 个映射文件,大多数但不是全部都将成为这些新属性的主机。在类中很容易定义它;但是,在映射中,除了创建实用程序或 xslt 并应用它(How to define reusable <generator> elements in hibernate mapping)之外,我没有找到任何参考。

但是我希望能够从这个“标准”映射中添加/修改/删除属性。

感谢任何回复

Edit1:我要添加的映射示例

<property name="TimeOfEdit" column="TimeOfEdit" type="DateTime" not-null="true"/>
<many-to-one name="EditedBy" column="FK_EditedBy" cascade="save-update" not-null="true" />

编辑2: 我删除了接受的解决方案,因为 NH 2.1.1 XML Entities are not working (NH-1236) 并且 NH 将抛出“此 XML 文档中禁止 DTD”

【问题讨论】:

【参考方案1】:

这取决于这些属性在您的类中是如何实现的。

如果它们都定义在基类或接口中,您可以在基类或接口中映射一次,然后使用union-subclass 派生。有一些限制。阅读this chapter in the NHibernate documentation 了解它。

如果您决定将它们放在一个类中,您可以将它们映射为用户类型。这将类似于组件,但您可以在用户类型中指定一些内容,例如类型名称、长度和其他内容。您仍然需要指定每个列的名称。

还有另一种选择:您可以使用 XML 实体。这是 NHibernate 支持的 XML 的一个相当原始的特性。阅读提到的this chapter in the NH reference documentation。

【讨论】:

XML Entities 似乎是最好的解决方案,但我不明白这句话“这种方法的缺点是 NHibernate 在执行多态查询时不会生成 SQL UNION。”是不是适当的 xml 与NH 使用映射之前的映射?除此之外,我在创建它时遇到了麻烦,我似乎找不到 XML 实体用法的工作示例。 最后我确实让它与 xml 实体一起工作,但是用它来定义 -ies 是完全不可能的。定义的 xml 可能只有一个根节点,因此只有 -s 是真正可行的。 -ing 不可行,类需要 元素【参考方案2】:

为您的具体情况创建一个特殊的代码生成器是您唯一的选择。

【讨论】:

你的意思是一次性的脚本/实用程序,它将操纵我想要的映射并注入元素? 我的意思是一个实用程序,它将获取某种信息源并创建hibernate期望的映射文件。这可能意味着读取现有的映射文件并从中添加/删除元素,但我更喜欢我有一个源(例如,源文件中的特殊 cmets)并生成整个输出文件的过程。否则,如果有人以混淆代码生成器的方式操作输出文件,您将遇到虚假错误。他会有错误,而你不会,诸如此类。【参考方案3】:

选项 1: -在基类中定义这3个属性

-让你的实体从这个基础继承

-设置“每个类层次结构表”

选项 2:

-将这3个属性定义为一个组件。

-您可以将这 3 个属性的映射放在一个可重复使用的文件中。

【讨论】:

不幸的是,组件解决方案需要一个额外的类,这不是我想要的。第一个选项是可行的,但是我想避免,因为抽象类的子类是在抽象类的映射文件中定义的,而我更喜欢一个解决方案,我转到 A 的类映射文件,并在那里定义(以某种方式)我想继承/注入抽象类的属性【参考方案4】:

您可以看看fluentNHibernate,它将为您简化映射工作。使用自动映射,您可能只需要一个抽象基类来定义这些属性。

【讨论】:

不幸的是,标准的 xml 映射已经布置好了。【参考方案5】:

似乎唯一的做法是使用动态映射 (http://ayende.com/Blog/archive/2008/05/01/Dynamic-Mapping-with-NHibernate.aspx)

因此,因为我已经定义了一个接口,我的实体将用于新属性(比如说 IAuditable),所以只需在 NH 会话初始化时运行适当的代码

Configuration cfg = new Configuration() Mappings mappings = cfg.CreateMappings(); 
foreach (var persistentClass in mappings.Classes) 
 
   if (persistentClass.MappedClass is IAuditable)
   
     ...
   

然后

cfg.BuildSessionFactory();

将其接线并准备好使用 对于大约 85 个类,性能影响可以忽略不计

【讨论】:

以上是关于有没有办法为 n-hibernate 映射定义可重用属性?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在所有节点完成加载后使用 PyYAML 构造映射构造对象?

没有可重定向到的 URL。提供一个 url 或在模型上定义一个 get_absolute_url 方法

对键盘使用原始输入时,有没有办法访问键重新映射?

有没有办法生成现有表及其相互关系的映射?

有没有办法在 Java 中映射大于 Integer.MAX_VALUE 的文件?

没有自定义 SQL 的 Dapper 中的多重映射