【问题标题】:How to do this Unidirectional NHibernate one-to-one mapping?如何进行这种单向 NHibernate 一对一映射?
【发布时间】:2010-06-07 16:03:39
【问题描述】:

这是NHibernate中单向一对一映射的问题。

Student.cs

public class Student
{
    public int ID { get; set; }
    public int Roll { get; set; }
    public int RegNo { get; set; }
    public string Name { get; set; }

    public StudentDetail StudentDetail { get; set; }
}

StudentDetail.cs

public class StudentDetail
{
    public int ID { get; set; }

    public string Father { get; set; }
    public string Mother { get; set; }
}

如何将这些类(hbm 映射文件看起来如何)映射到以下一对一关系的情况?

请仔细查看课程和表格。

我在哪里可以将<many-to-one> 标签放在Student.hbm.xmlStudentDetail.hbm.xml 中?如果我把它放在Student.hbm.xml 中,我如何映射列StudentDetail.StudentID,因为它在不同的表中?

所以这个映射:

<class name="Student" table="Student">
    <id name="ID" column="ID">
      <generator class="native"/>
    </id>

    .......

    <many-to-one class="StudentDetail" name="StudentDetail" column="StudentID" unique="true" cascade="all" />
  </class>

产生以下异常:

{"Invalid column name 'StudentID'."}

另一方面,&lt;many-to-one&gt; 不能放在 StudentDetail.hbm.xml 中。因为StudentDetail.cs 不包含任何Student 类型的属性。

我可以使用&lt;one-to-one&gt;-tag 吗?如果是,我应该把它放在哪里,Student.csStudentDetail.cs?又该如何配置呢?

【问题讨论】:

  • 如果你想在你的代码中使用一对一的关系,你应该考虑在数据库中也有这种关系(如果你可以改变数据库)。
  • 你的照片不见了。请将其添加回问题中。

标签: nhibernate one-to-one


【解决方案1】:

案例#1:

在学生中...

<one-to-one name="StudentDetail" 
            cascade="save-update,delete" 
            property-ref="Student" />

在 StudentDetail...

<many-to-one name="Student" 
             column="StudentID" 
             unique="true" 
             cascade="none" />

请注意,您的 StudentDetail 类中必须有一个引用 Student 对象(称为 Student)的属性。此外,根据您的使用情况,您的级联可能会有所不同。不过,您很可能想要删除级联。

unique="true" 确保 StudentDetail 端的一对一映射。

案例#2:

只需交换两个映射,确保将属性名称更改为相反的类。

查看此处了解更多信息: http://nhforge.org/blogs/nhibernate/archive/2009/04/19/nhibernate-mapping-lt-one-to-one-gt.aspx

【讨论】:

  • 抱歉,我忽略了这一点。试试这个:fabiomaulo.blogspot.com/2010/03/conform-mapping-one-to-one.html
  • 我不认为你可以做案例 #2。此外,案例#1 是一个更好的设计。其中一张表必须是主表,而且应该是 Student,因为如果没有 Student,StudentDetail 就不能真正存在。 StudentDetail 在逻辑上依赖于 Student,因此外键应该在 StudentDetail 中(即案例 #1)。
  • 我已经解决了案例#2。令人惊讶的是,我无法解决案例#1。详细信息已更新。
【解决方案2】:

您可以将其映射为一对多,隐藏集合属性,仅公开其第一个元素:

public class Student
{
    public virtual int ID { get; set; }
    public virtual int Roll { get; set; }
    public virtual int RegNo { get; set; }
    public virtual string Name { get; set; }

    protected virtual IList<StudentDetail> StudentDetails { get; set; }

    public virtual StudentDetail StudentDetail
    {
        get
        {
            if (StudentDetails.Count == 0) return null;
            return StudentDetails[0];
        }
        set
        {
            if (StudentDetails.Count != 0) throw new Exception();
            StudentDetails.Add(value);
            value.Student = this;
        }
    }
}

您可以比这更好地处理 setter - 关键是确保您不会将多行添加到一对多。显然,StudentDetails 已被映射,但 StudentDetail 不在您的 .hbm.xml 或 Fluent 映射中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    • 2014-11-14
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多