Nhibernate карта / дизайн проблема - PullRequest
0 голосов
/ 13 марта 2012

Эта проблема связана либо с моим плохим дизайном проекта, либо с недостатком знаний о том, как использовать nhibernate, либо с обоими (просто заметьте, я виню nhibernate в моем плохом дизайне проекта).Вот оно:

В моей доменной модели у меня есть следующее (я упустил много лишних, чтобы упростить задачу):

Объект Event:

public class EventBO 
{

    public int ID { get; set; }

    public String Name
    {
        get;
        set;
    }

    private List<InviteeBO> _invitees = null;

    public List<InviteeBO> Invitees
    {
        get { return _invitees; }
        set { _invitees = value; }
    }
}

И объект приглашенного:

public class InviteeBO 
{

    public int ID { get; set; }

    public String Name
    {
        get;
        set;
    }

    private List<InviteeBO> _invitees = null;

    public List<InviteeBO> Invitees
    {
        get { return _invitees; }
        set { _invitees = value; }
    }

    private EventBO theEvent;

    public EventBO TheEvent
    {
        get { return theEvent; }
        set { theEvent = value; }
    }

    private InviteeBO invitedByUser = null;

    public InviteeBO InvitedByUser
    {
        get { return invitedByUser; }
        set { invitedByUser = value; }
    }
}

При создании события его создатель автоматически добавляется в список Event.Invitees.Затем этот же человек может добавить неограниченное количество приглашенных, которые затем добавляются в список «Приглашенные» в объекте «Приглашенный», который был только что добавлен в событие.Причина в том, что мне нужно следить не только за тем, кто был добавлен на мероприятие, но и за тем, кто кого добавил.

Моя проблема заключается в следующем: когда я сохраняю событие, EventID добавляется в соответствующий столбец в БД для каждого Приглашенного, присутствующего в списке приглашенных на Событие (в таблице БД «Приглашенные»).Кроме того, если Приглашенный в этом списке Event.Invitees приглашает друзей (и, следовательно, добавляет приглашенных в свой соответствующий список Invitee.Invitees), то при сохранении события будет правильно записанIDID Приглашенного, который выполнил приглашение всем Приглашенным (также в таблице приглашенных БД).ПРОБЛЕМА: EventID не добавляется к дочерним Приглашенным всем приглашенным в списке Event.Invitees.

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

Независимо от того, вот соответствующие части файлов отображения событий и приглашенных:

Event.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="DAL"
                   namespace="DAL.DAO.Entities">
  <class name="EventDO" table="Events">
    <id name="ID">
      <column name="ID"/>
      <generator class="native" />
    </id>
    <property name="Name">
      <column name="Name"/>
    </property>
    <property name="Description">
      <column name="Description"/>
    </property>    
    <bag name="Invitees" table="Invitees" inverse="false" cascade="all" lazy="false" >
      <key column="EventID"/>
      <one-to-many class="InviteeDO" />
    </bag>

  </class>
</hibernate-mapping>

Invitee.hbm.xml:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DAL" namespace="DAL.DAO.Entities" >
  <class name="InviteeDO" table="Invitees">
    <id name="ID">
      <generator class="identity"/>
    </id>
      <property name="FullName"/>
      <many-to-one name="TheEvent"  cascade="none" column="EventID" lazy="false" />
      <bag name="Contacts" table="Contacts" inverse="false" cascade="all" lazy="false" >
        <key column="ContactOfUserID"/>
        <one-to-many class="ContactDO" />
      </bag>
      <bag name="Invitees" table="Invitees" inverse="false" cascade="save-update" lazy="false" >
        <key column="InvitedByID" />
        <one-to-many class="InviteeDO"/>
      </bag>
      <property name="IsOrganizer"/>
      <property name="IsCreator"/>


  </class>
</hibernate-mapping>

ОБНОВЛЕНИЕ @ Роберто Эрнандес - Во-первых, спасибо за ответ.Я очень, очень ценю это.

Во-вторых, вы взяли на себя инициативу и провели тестирование, используя только мои DAL и DO, и это сработало.Очевидно, что что-то не так с функциями, которые конвертируют мои DO в BO.

Есть еще кое-что, что я сделал неправильно, на что вы указали.Я добавил дочернего приглашенного к родительскому приглашенному и родительского приглашенного на событие. Приглашенные.Затем я предположил, что сохранение события будет выполнять всю необходимую настойчивость, в том числе для приглашенных детей.Очевидно, я был неправ, и мне нужно было также добавить parentInvitee для дочернего элемента, а дочерний элемент для Event.Invitees.Спасибо!

1 Ответ

1 голос
/ 13 марта 2012

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

// This is my SessionFactory (Not Relevant!)
using (var session = NhSessionFactory.GetSession(generatedatabase: false))
{
using (var tran = session.BeginTransaction())
{
    var theEvent = new EventBO();
    theEvent.Name = "EventName";

    var parentInvitee = new InviteeBO();
    parentInvitee.Name = "Parent";
    theEvent.Invitees.Add(parentInvitee);

    for (int index = 0; index <= 5; index++)
    {
        var childInvitee = new InviteeBO();
        childInvitee.Name = string.Format("Child {0}", index);
        childInvitee.InvitedByUser = parentInvitee;  // Adding invited by user.

        parentInvitee.Invitees.Add(childInvitee);
        theEvent.Invitees.Add(childInvitee);   // Adding child invitees to Event.
    }

    session.SaveOrUpdate(theEvent);
    tran.Commit();
}
}

Хотя приведенный выше код работает, я бы рекомендовал рефакторинг всего этого в ваши объекты BO. Например, добавление метода AddInvitee в класс Event, который обрабатывает установку свойств в дочернем объекте.

ВНИМАНИЕ: у вас, похоже, есть слой отображения, который вы не показываете нам, который обрабатывает отображение из BO в DO. Я ответил наилучшим образом, не зная, что у вас есть в этом слое.

...