代码之家  ›  专栏  ›  技术社区  ›  Webjedi

外键约束正在阻止NHibernate保存子记录

  •  2
  • Webjedi  · 技术社区  · 17 年前

    我有两张桌子:

    支援票

    支撑物
    支持日期

    支持通知单

    支持TicketNoteID
    支持通知日期
    支撑物

    使用外键约束,这样我就没有任何未关联的注释…在SQL中,该约束工作正常。

    在我的SupportTicket类上,我有一个IList SupportTicketNotes属性,并将其映射为一个包(可能真的应该是一个集合,但这目前并不重要)。负载工作得很好。问题是,如果我新建了一个SupportTicket,新建了一个SupportTicketNote,将注释添加到该票据并保存该票据。nHibernate正在插入SupportTicket,然后插入SupportTicketNote,其SupportTicketId为零,这当然会因为fk约束而爆炸。如果删除约束,它将以0的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 回复  |  直到 17 年前
        1
  •  2
  •   Jamie Ide    17 年前

    您如何在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
  •  4
  •   Stuart Childs    17 年前

    我还没有看到你的完整地图,但首先想到的是这一部分 documentation :

    非常重要的注意事项 如果 <key> A列 <one-to-many> 协会 被宣布 NOT NULL ,氨苄酯可能 导致约束冲突 创建或更新关联。到 防止这个问题, 必须使用 双向联系 与 多值端(套或包) 标记为 inverse="true" . 见 双向讨论 本章后面的关联。

        3
  •  -2
  •   Eoin Campbell    17 年前

    您需要以这样的方式编写您的函数:在添加SupportTicketNote之前,新的SupportTicket的持久性就发生了。

    例如

    SupportTicket st = new SupportTicket();
    SupportTicketNote stn = new SupportTicketNote();
    
    ///Code to set properties on both objects
    
    st.Save();
    st.SupportTicketNotes.Add(stn);
    st.Save();