NHibernate: Как мне сопоставить детей нескольких родителей общего типа в одну таблицу? - PullRequest
2 голосов
/ 06 апреля 2009

Есть ли способ заставить NHibernate разрешить мне хранить несколько ChildObjects в ChildObjectTable, но отсылать их обратно к различным ParentObjects? Или мне нужно создать отдельный класс / таблицу ChildObject для каждого типа ParentObject?

Я свел это к следующему, я пытаюсь сопоставить эти объекты:

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; }   
}

в следующую структуру таблицы:

ParentObjectTableA
  Id bigint

ParentObjectTableB
  Id bigint

ChildObjectTable
  Id bigint
  ParentId bigint
  ParentQualifier varchar(50)

Ответы [ 3 ]

1 голос
/ 06 апреля 2009

Возможно, вы могли бы создать абстрактный базовый класс для ваших родительских классов? Таким образом, данный дочерний объект может ссылаться на абстрактный тип своего родителя.

Например, у вас может быть класс с именем ParentBase, который расширяет ParentClassA и ParentClassB. Ваш дочерний объект будет иметь ссылку обратно на ParentBase.

Все это возможно с различными моделями наследования NHibernate .

0 голосов
/ 08 апреля 2009

Я получил версию наследования, работающую также с интерфейсом в качестве базы, и хотел опубликовать ее здесь для завершения.

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

Большая «ошибка», о которой следует знать, это то, что объект Child напрямую ссылается на Id только в таблице IParents. И каждый экземпляр объекта Parent или Parent2 связан с объединенным вызовом между IParents и Parents или Parents2, в зависимости от того, с каким типом производного объекта вы на самом деле работаете.

Я еще не тестировал это с классом с несколькими интерфейсами, но мне нужно это тоже проверить.

Что мне не нравится в модели наследования, так это то, что мне нужен общий интерфейс / базовый класс. Я не уверен, почему я против этого бесцеремонности, это просто кажется неуклюжим.

Я думаю, что я собираюсь накатить с помощью метода кросс-таблицы на данный момент и вернуться к этому позже, если потребуется.

0 голосов
/ 06 апреля 2009

Следующие карты работают с точки зрения объекта. Мне не слишком нравится идея использования кросс-таблиц, но я думаю, что это может быть чище, чем пытаться справиться с наследованием Я также собираюсь взглянуть на этот вариант и опубликую свои выводы здесь для завершения. Комментарии приветствуются.

Отображение ParentObjectA

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

Отображение ParentObjectB

<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,
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...