C# NHibernate:我如何映射多个父母';将普通类型的子项放入单个表中?

C# NHibernate:我如何映射多个父母';将普通类型的子项放入单个表中?,c#,nhibernate,C#,Nhibernate,有没有办法让NHibernate允许我在ChildObjectTable中存储多个ChildObject,但将它们引用回不同的ParentObject?还是必须为每种ParentObject类型创建单独的ChildObject类/表 我将其归结为以下内容,我正在尝试映射这些对象: public class ParentObjectA { public virtual Int64 Id { get; private set; } public virtual IDictionar

有没有办法让NHibernate允许我在ChildObjectTable中存储多个ChildObject,但将它们引用回不同的ParentObject?还是必须为每种ParentObject类型创建单独的ChildObject类/表

我将其归结为以下内容,我正在尝试映射这些对象:

public class ParentObjectA
{
    public virtual Int64 Id { get; private set; }

    public virtual IDictionary<int, ChildObject> Children { get; private set; }
}

public class ParentObjectB
{
    public virtual Int64 Id { get; private set; }

    public virtual IDictionary<int, ChildObject> Children { get; private set; }
}

public class ChildObject
{
    public virtual Int64 Id { get; private set; }   
}

也许您可以为父类创建一个抽象基类?这样,给定的子对象就可以引用其父对象的抽象类型

例如,可以有一个名为ParentBase的类,ParentClassA和ParentClassB对其进行扩展。您的子对象将具有对ParentBase的引用


这在NHibernate的各种地图上都是可能的。

以下地图似乎是从对象的角度工作的。我不太喜欢使用交叉表,但我认为这可能比处理继承更干净。我也要看看这个选项,为了完成,我会把我的发现贴在这里。欢迎评论

ParentObjectA的映射

<map name="Children" table="ParentAxChildObject">
    <key column="ParentId" />
    <index column="ChildObjectNumber" type="Int32" />
    <many-to-many class="ChildObject" />
</map>

我已经将继承版本与作为基础的接口一起工作,并希望将其发布到这里以供完成

public interface IParent
{
    IList<Child> children { get; set; }
    void AddChild(Child child);
    Int64 Id { get; set; }
    Child GetChild();
}

public class Parent : IParent
{
    public virtual IList<Child> children { get; set; }

    public Parent()
    {
        children = new List<Child>();
    }

    public virtual void AddChild(Child child)
    {
        children.Add( new Child() );
    }

    public virtual Int64 Id { get; set; }

    public virtual Child GetChild()
    {
        return children.First();
    }
}

public class Parent2 : IParent
{
    public virtual IList<Child> children { get; set; }

    public Parent2()
    {
        children = new List<Child>();
    }

    public virtual void AddChild(Child child)
    {
        children.Add(new Child());
    }

    public virtual Int64 Id { get; set; }

    public virtual Child GetChild()
    {
        return children.First();
    }
}


public class Child
{
    public virtual Int64 Id { get; private set; }
}
这里需要注意的一个大问题是,子对象仅直接引用IParents表中的Id。父对象或父对象2的每个实例都绑定到IParents与父对象或父对象2之间的联接调用,具体取决于您实际使用的派生对象类型

我还没有用一个有多个接口的类来测试它,但是我也需要测试它

我不喜欢继承模型的一点是,我需要一个公共接口/基类。我不知道为什么我会反对这种即兴表演,它看起来很笨重


我想我现在要使用交叉表方法,如果有必要的话,以后再讨论这个问题。

我突然想到,我可能可以用交叉表来解决这个问题,这将使我在NHibernate的多对多领域中。如果有一种更简单的方法将其融入到这个结构中,我宁愿不这样做。这是真的。我实际上在其他地方使用了这种技术,但我甚至没有想到在这里应用它,因为我试图避免使用公共基类。这也适用于接口吗?我不确定NHibernate如何处理映射场景中的接口。应该注意的是,映射中的表属性似乎没有记录在NHibernate文档中。当我发现它在默认情况下试图用“name”属性构建一个交叉表时,我就猜到了。这会创建一个合并的
子类
集合吗?整洁的非常有趣的方法,我以前从未见过。
<map name="Children" table="ParentBxChildObject">
    <key column="ParentId" />
    <index column="ChildObjectNumber" type="Int32" />
    <many-to-many class="ChildObject" />
</map>
ParentAxChildObject
    [ParentId] [bigint] NOT NULL,
    [elt] [bigint] NOT NULL,
    [ChildObjectNumber] [int] NOT NULL,

ParentBxChildObject
    [ParentId] [bigint] NOT NULL,
    [elt] [bigint] NOT NULL,
    [ChildObjectNumber] [int] NOT NULL,
public interface IParent
{
    IList<Child> children { get; set; }
    void AddChild(Child child);
    Int64 Id { get; set; }
    Child GetChild();
}

public class Parent : IParent
{
    public virtual IList<Child> children { get; set; }

    public Parent()
    {
        children = new List<Child>();
    }

    public virtual void AddChild(Child child)
    {
        children.Add( new Child() );
    }

    public virtual Int64 Id { get; set; }

    public virtual Child GetChild()
    {
        return children.First();
    }
}

public class Parent2 : IParent
{
    public virtual IList<Child> children { get; set; }

    public Parent2()
    {
        children = new List<Child>();
    }

    public virtual void AddChild(Child child)
    {
        children.Add(new Child());
    }

    public virtual Int64 Id { get; set; }

    public virtual Child GetChild()
    {
        return children.First();
    }
}


public class Child
{
    public virtual Int64 Id { get; private set; }
}
<class name="IParent" table="IParents">
    <id name="Id" unsaved-value="0">
        <column name="Id" sql-type="bigint" />
        <generator class="hilo" />
    </id>

    <bag name="children" cascade="all">
        <key column="ParentId" />
        <one-to-many class="Child" />
    </bag>

    <joined-subclass name="Parent" table="Parents" >
        <key column="ParentId" />
    </joined-subclass>

    <joined-subclass name="Parent2" table="Parents2" >
        <key column="ParentId" />
    </joined-subclass>
</class>

<class name="Child" table="Children">
    <id name="Id" unsaved-value="0">
        <column name="Id" sql-type="bigint" />
        <generator class="hilo" />
    </id>
</class>
IParents
    Id bigint

Parents
    ParentId bigint

Parents2
    ParentId bigint

Children
    Id bigint
    ParentId bigint