我在Person类和Employee之间有一对一的关系。我希望INSERT从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);
}
答案 0 :(得分:2)
Yads基本上是正确的。第二个<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 PayRollNo
,则默认列名为PayRollNo
。如果属性的类型为int
,则默认的映射类型也为int
。答案 1 :(得分:0)
根据此http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-onetoone您错过了人物映射中constrained="true"
元素中的<one-to-one>
。
答案 2 :(得分:0)
将session.Save()方法放在事务中。或者在调用save方法之后使用session.Flush()方法。
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