如何在nHibernate中映射一个继承抽象类并同时实现接口的类?

Posted

技术标签:

【中文标题】如何在nHibernate中映射一个继承抽象类并同时实现接口的类?【英文标题】:How to map a calss that inherits an asbtract class and implements an interface at the same time in nHibernate? 【发布时间】:2020-05-12 16:35:47 【问题描述】:

想象一下我们有这个实体:

public interface ISomeone



public abstract class Parent



public class Child : Parent , ISomeone



public class Orphan : ISomeone



public class MyHeart

  public ISomeone Person get;set;

那么如何在 nhibernate 中映射这些所有类? 我更喜欢为“Parent”、“Orphane”和“MyHeart”类使用单独的表。 "Parent" 、 "Orphan" 和 "MyHeart" 应该作为聚合根持久存在,并且 MyHeart 可以与任何实现了 "ISomeone" 接口的实体有关系。因此它可以扩展到具有不同 id 形式的不同表的不同实体类型

【问题讨论】:

我认为你应该首先问问自己你希望你的数据看起来如何。这与您使用的 ORM 框架的类型无关。您在此处给出的示例似乎是非常假设的,而不是您实际要查找的内容的表示。没有一个类真的有任何属性。为什么Parent 没有实现ISomeone?为什么你想要一个接口或抽象类来表示你的数据模型,它是非常具体的,根本不是抽象的? 请注意,我并不是说您不能使用抽象类来映射您的数据,但我不确定您是否需要/应该这样做。 我同意 Xerillio,这是可能的,但是,您希望如何使用“父母”? MyHeart 引用了 ISomeone,但是,该接口的唯一实现是“Child”和“Orphan”。这就是你所期待的,MyHeart.Person 要么是“孩子”,要么是“孤儿”?如果是这样,抽象类似乎不会影响您的映射。如果没有,我看不出抽象类如何影响您的映射。 感谢大家重播。我想使用“Parent”、“Orphane”和“MyHeart”作为聚合根,然后所有这些都应该坚持下去。 Parent 和它的继承者应该在同一个表中持久化可能鉴别器可以在这里发挥一些作用。但重点是 MyHeart 是指一些实现 ISomeone 的实体。当从 db 中检索 MyHeart 时应该引用正确的实体。我希望它可以说清楚 我做了一些编辑来解释我的意思 【参考方案1】:

我终于找到了解决方案 “Any”方法就是答案,简单地说,我们用这个方法为另一个世界的 IPerson 的每个可能值定义一些元值,每个实现这个接口的类都应该在“Any”方法中定义,然后 nHibernate 保持 Id 和 MetaValue。

我的示例的代码映射如下:

public class MyHeartMapping : ClassMapping<MyHeart>

    public MyHeartMapping()
    
        Id(x => x.Id, x => x.Generator(Generators.Native));

        Any(p => p.Person, typeof(long), m => 

            m.MetaValue("Child", typeof(Child));
            m.MetaValue("Orphane", typeof(Orphane));
            m.Columns(i => i.Name("PersonId"), c => c.Name("ClassName")); );
    


public class ParentMapping : ClassMapping<Parent>

    public ParentMapping()
    
        Id(x => x.Id, x => x.Generator(Generators.Native));
        Discriminator(c => c.Column("Discriminator"));
    


public class ChildMapping : SubclassMapping<Child>

    public ChildMapping()
    
        DiscriminatorValue("Child");
    


public class OrphaneMapping : ClassMapping<Orphane>

    public OrphaneMapping()
    
        Id(x => x.Id, x => x.Generator(Generators.Native));
    

【讨论】:

以上是关于如何在nHibernate中映射一个继承抽象类并同时实现接口的类?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 NHibernate 联合子类映射抽象属性?

如何在多个实体到另一个实体之间创建 NHibernate 关系映射(即继承映射)

如何使用 Fluent NHibernate 自动映射禁用特定抽象基类的子类化

如何在运行时从 nhibernate 映射文件生成实体类

如何 NHibernate 将多个类映射到同一个表

命名查询和继承