Foreign Key Constraint阻止NHibernate保存子记录

时间:2009-05-01 13:05:47

标签: nhibernate

我有两张桌子:

SupportTicket

SupportTicketID
SupportTicketDate

SupportTicketNote

SupportTicketNoteID
SupportTicketNoteDate
SupportTicketID

使用外键约束,所以我在sql中没有任何无关联的Notes ...约束正常工作。

在我的SupportTicket类中,我有一个IList SupportTicketNotes属性,并将其映射为一个包(可能真的应该是一个集合,但目前并不重要)。负载工作得很好。问题是如果我新建一个SupportTicket,新建一个SupportTicketNote,将注释添加到故障单并保存故障单。 NHibernate插入SupportTicket,然后插入SupportTicketNote,其SupportTicketID为零,当然由于FK约束而爆炸。如果我删除约束,它将插入SupportTicketID为零,然后返回并使用正确的ID值对SupportTicketNote进行更新......但这似乎是错误的。我可能在映射中做了什么导致了吗?

更新以在子对象上包含多对一映射

这是我目前对SupportTicket的映射:

<bag name="_supportTicketNotes" table="SupportTicketNotes" access="field" cascade="save-update" inverse="true" >
  <key column="SupportTicketID" foreign-key="FK_SupportTicketNotes_supporttickets" ></key>
  <one-to-many class="NhibernateSample.DomainModel.SupportTicketNote, NhibernateSample.DomainModel" />
</bag>  

这是我对SupportTicketNote的映射(注意我的SupportTicketNote类同时具有SupportTicketID和SupportTicket对象属性):

 <many-to-one name="SupportTicket"   class="NhibernateSample.DomainModel.SupportTicket, NhibernateSample.DomainModel"   column="SupportTicketId" cascade="all"/>  

3 个答案:

答案 0 :(得分:4)

我还没有看到你的完整地图,但是我想到的第一件事就是来自documentation的这一部分:

  

非常重要的注意事项:如果是<key>   <one-to-many>关联的列   声明NOT NULL,NHibernate可以   导致约束违规的时候   创建或更新关联。至   防止这个问题,你必须使用一个   双向关联与   许多有价值的结束(套装或包)   标记为inverse="true"。见   关于双向的讨论   本章后面的协会。

答案 1 :(得分:2)

您如何在SupportTicketNote上映射父SupportTicket属性?在向集合添加SupportTicketNote时是否设置了SupportTicket属性?我几乎总是遵循这种模式:

public class SupportTicket
{
    private IEnumerable<SupportTicketNote> _notes = new List<SupportTicketNote>();

    public IEnumerable<SupportTicketNote> Notes
    {
        get { return _notes; }
    }

    public void AddNote(SupportTicketNote note)
    {
        note.SupportTicket = this;
        _notes.Add(note)
    }

    public void RemoveNote(SupportTicketNote note)
    {
        note.SupportTicket = null;
        _notes.Remove(note)
    }
}

编辑添加: 您的SupportTicketNote映射看起来不对。它与SupportTicket应该是多对一的,你根本不应该映射SupportTicketId。我一直在使用Fluent NHibernate一段时间,但我认为XML映射应如下所示:

<many-to-one name="SupportTicket"
   class="NhibernateSample.DomainModel.SupportTicket, NhibernateSample.DomainModel"
   column="SupportTicketId" cascade="all"/>

答案 2 :(得分:-2)

您需要编写函数,以便在添加SupportTicketNote之前发生New SupportTicket的持久性

e.g。

SupportTicket st = new SupportTicket();
SupportTicketNote stn = new SupportTicketNote();

///Code to set properties on both objects

st.Save();
st.SupportTicketNotes.Add(stn);
st.Save();