NHibernate-一对一级联设置

NHibernate-一对一级联设置,nhibernate,nhibernate-mapping,Nhibernate,Nhibernate Mapping,我在Person类和Employee之间有一对一的关系。我希望插入的内容能够从该人员级联到该员工。然而,这并没有发生。我在一对一关系元素上尝试了cascade='all'和cascade='save-update',但没有成功 “我的对象”的结构如下所示: public class Person { public virtual Employee Employee { get; set; } public virtual int Age { get; set; } pub

我在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>

根据这一点,您缺少Person映射中
元素中的
constrated=“true”

Yads基本上是正确的。第二个
(从员工到个人)需要
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”
    。阅读
  • 为类使用更多DDD名称。您有一个表示人员的实体,其数据存储在Person表中。你为什么叫它PersonDataContext
  • 您正在映射到属性,而不是字段。在类中显示属性的代码,而不是底层字段
  • 您不需要使用默认值进行覆盖。如果属性名称为
    PayRollNo
    ,则默认列名为
    PayRollNo
    。如果属性的类型为
    int
    ,则默认映射类型也为
    int
将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提交到数据库。默认情况下,在transaction.Commit()方法上会发生这种情况


有关更多信息,请参阅Nhibernate文档

谢谢您的回复。我已经应用了你所有的建议,但仍然不起作用,我已经上传了一个示例源代码到我想知道你是否有时间快速查看一下。非常感谢。NimaFrom正在阅读另一个问题(您确实标记了答案),看起来您没有按照我的代码说明(事务和提交)我应用了您的建议,但仍然不起作用,我已将示例源代码上载到bit.ly/gNlAWr我想知道您是否有时间快速查看一下。@Nima,
contained
属性位于员工映射上,但应位于人员映射上。看起来您的外键检查也应该在Employee表上,而不是Person表上。谢谢Yads。你说的外键检查是什么意思?@Nima实际上你所有的东西看起来都是反向的。它是具有外键生成的人。它的工作原理与你认为的相反。请彻底重读本节。您可能不需要FK约束。@Yads我的示例与您发送给我的文章中的示例有些不同。在我的示例中,Person表中的PersonID是Person表中的PK,Employee表中的PK和FK。我说得对吗
       using (var trans = session.BeginTransaction())
            {
                try
                {
                    trans.Begin();
                    session.Save(employee);
                    trans.Commit();
                }
                catch
                {
                    trans.Rollback();
                    throw;
                }
            }