NHibernate - индивидуальные каскадные настройки - PullRequest
0 голосов
/ 22 января 2011

У меня отношения один-к-одному между классом Person и Employee. Я ожидаю, что ВСТАВКА будет каскадом от Человека к Сотруднику. Однако этого не происходит. Я пробовал cascade = 'all' и cascade = 'save-update' для элемента отношения один-к-одному, но это не сработало.

Структуры моих объектов следующие:

public class Person
{
    public virtual Employee Employee { get; set; }
    public virtual int Age { get; set; }
    public virtual string Forename { get; set; }
    public virtual string Surname { get; set; }
    public virtual int PersonID { get; set; }
}

public class Employee
{
    public virtual int PersonID { get; set; }
    public virtual string PayRollNo { get; set; }
    public virtual int Holidays { get; set; }
    public virtual Person Person { get; set; }
}

Отображение файлов показано ниже:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="Employee, Employee.DAL" table="`Employee`"  >
    <id name="PersonID" column="`PersonId`" type="int">
      <generator class="native" />
    </id>
    <property type="string" length="30" name="PayRollNo" column="`PayRollNo`" />
    <property type="int" name="Holidays" column="`Holidays`" />
    <one-to-one name="Person"  class="Person" cascade="all"/>
  </class>
</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
  <class name="Person, Employee.DAL" table="`Person`"  >    
    <id name="PersonID" column="`PersonId`">
      <generator class="foreign">
        <param name="property" >Employee</param>
      </generator>
    </id>
    <property type="string" name="Forename" column="`Forename`" />
    <property type="string" name="Surname" column="`Surname`" />
    <property type="int" name="Age" column="`Age`" />
    <one-to-one name="Employee" class="Employee"  constrained="true"  />
  </class>
</hibernate-mapping>

Код для инициации объектов и их сохранения:

var employee = new Employee();

    employee.Person = new Person { Employee = employee };

    ISessionFactory sessionFactory = (new Configuration()).Configure().BuildSessionFactory();

    employee.Person.Age = 27;
    employee.Person.Forename = "N";
    employee.Person.Surname = "M";

    employee.PayRollNo = "12";
    employee.Holidays = 27;

    using (var session = sessionFactory.OpenSession())
    {
        session.Save(employee);        
    }

Ответы [ 3 ]

2 голосов
/ 22 января 2011

Ядс по сути прав.Второй <one-to-one> (от сотрудника к человеку) нуждается в constrained="true".При этом должен работать следующий код:

using (var session = sessionFactory.OpenSession())
using (var tx = session.BeginTransaction())
{
    var person = new PersonDataContext();
    person.Employee = new EmployeeDataContext { Person = person };
    session.Save(person);
    tx.Commit();
}

Несколько дополнительных предложений:

  • Не , не , использовать lazy="false".Прочитайте http://ayende.com/Blog/archive/2010/08/04/nhibernate-is-lazy-just-live-with-it.aspx
  • Используйте больше названий DDD для ваших классов.У вас есть сущность, представляющая персона, чьи данные хранятся в таблице персон.Почему вы называете это PersonDataContext ?
  • Вы сопоставляете свойства, а не поля.Покажите код для ваших свойств в ваших классах вместо базовых полей.
  • Вам не нужно переопределять значения по умолчанию.Если имя свойства PayRollNo, имя столбца по умолчанию - PayRollNo.Если тип свойства int, сопоставляемый тип по умолчанию тоже int.
0 голосов
/ 24 января 2011

Поместите метод session.Save () в транзакцию. Или используйте метод session.Flush () после вызова метода save.

       using (var trans = session.BeginTransaction())
            {
                try
                {
                    trans.Begin();
                    session.Save(employee);
                    trans.Commit();
                }
                catch
                {
                    trans.Rollback();
                    throw;
                }
            }

Nhibernate иногда сохраняет операторы SQL для синхронизации даты в памяти. Метод session.Flush () фиксирует SQL в базе данных. Это происходит по умолчанию в методе transcation.Commit ().

Для получения дополнительной информации обратитесь к документации Nhibernate http://nhibernate.info/doc/nh/en/index.html#manipulatingdata-flushing

0 голосов
/ 22 января 2011

Согласно этому http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-onetoone Вам не хватает constrained="true" в элементе <one-to-one> в сопоставлении персонажа.

...