Помогите с NHibernate Вставить / Обновить - PullRequest
1 голос
/ 24 декабря 2009

Я новичок в NHibernate и нашел его чрезвычайно интересным. Я пытался сохранить объекты в таблице сопоставления (таблица, которая разрывает отношения «многие ко многим» при проектировании реляционной базы данных), но пока не смог этого сделать. Однако я могу получить данные из таблицы сопоставления, используя мое текущее отображение спящего режима.

Вот как выглядит моя база данных:

Группы (groupId, groupName) Отчеты (reportID, reportName) GroupReports (groupId, reportId)

Очень типичные и простые отношения с точки зрения моделирования данных.

Я знаю, что этот вопрос задавался много раз, и я прочитал много из них. Поверь мне, я действительно это сделал.

Вот мое отображение для класса сущностей группы:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer">
  <class name="DataTransfer.Group, DataTransfer" table="GROUPS">
    <id name="GroupId">
      <column name="groupId" sql-type="int" not-null="true"/>
      <generator class="native"/>
    </id>
    <property name="GroupName" column="groupName" type ="string" length="150" not-null="true"/>       
    <bag name="Reports" cascade="none" inverse="true">
      <key column="groupId"/>
      <many-to-many column="reportId" class="DataTransfer.Report, DataTransfer"/>      
    </bag>
  </class>
 </hibernate-mapping>

И мое сопоставление для класса сущностей Report ниже:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer">
  <class name="DataTransfer.Report, DataTransfer"  table="REPORTS" >
    <id name="ReportId" column="reportId" type="int" unsaved-value="0">
      <generator class="native"/>
    </id>        
    <property name = "ReportName" column="reportName" type="string" length="250" not-null="true"/>
    <bag name="MappedGroups" table="GroupReports" cascade="all" inverse="false" lazy="true">
      <key column="reportId"/>
      <many-to-many class="DataTransfer.Group, DataTransfer" column="groupId" />          
    </bag>    
  </class>
</hibernate-mapping>

Согласно тому, что я прочитал, эти сопоставления должны позволить мне как извлекать, так и сохранять данные сопоставления из ассоциированной таблицы GroupReports. Мой код модульного теста показывает только оператор выбора SQL, без вставок в таблицу сопоставления.

Учитывая мои отображения, что нужно сделать, чтобы сохранить данные отображения?

Ответы [ 2 ]

1 голос
/ 24 декабря 2009

Предполагая, что вы настраиваете свою сессионную фабрику / сеанс правильно (так как вы получаете операторы SELECT), я бы поспорил, что вы не используете транзакции или сбрасываете сеанс.

Рекомендуемый способ обновления данных в NHibernate - всегда использовать транзакцию. Примерно так:

using(var session = sessionFactory.OpenSession())
using(var tx = session.BeginTransaction())
{
    var group = new Group {GroupName="Programmers Anonymous"};
    session.Save(group);
    tx.Commit();
}

Это должно помочь вам.

- ОБНОВЛЕНИЕ -

Так что после прочтения вашего другого вопроса, кажется, что вы хотите этот код ...

session.Save(report);

для автоматического сохранения групп. Но в вашем отображении вы определили коллекцию групп как cascade="none". Измените это на cascade="save-update", и оно исправит это.

Надеюсь, что это отвечает на ваш вопрос.

0 голосов
/ 28 декабря 2009

Спасибо, Бен, за твой ответ. Я не смог найти свой пост до сегодняшнего дня. : -).

На самом деле я использовал транзакцию в своем коде. Вот код для моего метода Add:

 public int Add(Report obj)
        {
            //set the flush mode to Never so that session.save() does not cause a flush until the commit() 
            //on transaction is called
            _session.FlushMode = FlushMode.Never;
            using (ITransaction tx = _session.BeginTransaction())
            {
                try
                {
                    int newId = (int)_session.Save(obj);
                    tx.Commit();//this will cause the a flush of the session
                    return newId;
                }
                catch (HibernateException)
                {
                    tx.Rollback();
                    throw;
                }
            }
        }

Я могу сохранить родительский объект с этим кодом. В моем случае я могу сохранить объект отчета в базе данных. Вот мой код модульного теста для сохранения родительских и дочерних объектов с использованием сопоставления отношений «многие ко многим»:

const string reportCd = "TE";
const string reportName = "Test Report 6";
Report report = new Report;
report.ReportCd = reportCd;
report.ReportName = reportName;
report.IsPublicFlag = 0;

IList<Group> groups = new List<Group>();

Group group = new Group();

group.GroupId = 2;
groups.Add(group);

report.Groups = Groups;
_provider.Add(report);

Объект _provider - это мой объект Dao, у которого есть метод Add, упомянутый выше.

Кроме того, поскольку Report и Group являются объектами «многие ко многим», они содержат IList друг друга. Объект Groups of Report является IList объекта Group, а объект Group имеет IList Reports.

Еще раз, спасибо за вашу помощь.

John

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...