Nhibernate保存失败 - 一对多

时间:2014-04-08 20:37:20

标签: .net nhibernate sql-server-2008-r2

我有一个书对象,有步骤。这些反映在下面的映射文件和类中

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="DA"
                   namespace="DA">

  <class name="Book" table ="Book">
    <id name="Id">
      <generator class="native"/>
    </id>
    <property name="Name" />
    <property name="Description"  />
    <property name="CreateDate" />
    <property name="ModifiedDate" />
    <property name="AuthorId" />


    <set name="Steps" table="Steps" cascade="all">
      <key column="BookId"/>
      <one-to-many class="Step"/>
    </set>
  </class>

</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="DA"
                   namespace="DA">
  <class name="Step" table ="Steps">
    <id name="Id">
      <generator class="native"/>
    </id>
    <property name="BookId" />
    <property name="Name"  />
</class>

</hibernate-mapping>


public class Book
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual string Description { get; set; }
    public virtual DateTime CreateDate { get; set; }
    public virtual DateTime ModifiedDate { get; set; }
    public virtual ICollection<Step> Steps { get; set; }
    public virtual int AuthorId { get; set; }
}

public class Step
{
    public virtual int Id { get; set; }
    public virtual int BookId { get; set; }
    public virtual string Name { get; set; }
}

我有一个测试,看起来添加了因为添加了子对象步骤而失败的书。 当这些不存在时,它会将书籍条目添加得很好。 似乎一对多的关系出现了问题

public void AddBook()
{
    Book b = new Book();
    b.AuthorId = 1;
    b.CreateDate = DateTime.Now;
    b.Description = "<Insert book Desription>";
    b.ModifiedDate = DateTime.Now;
    b.Name = "<Book Title>";
    b.Steps = new List<Step>();
    b.Steps.Add(new Step() { Name = "Step1" });
}

调用

public bool AddBook(Book BookToAdd)
{

    using (var tx = Session.BeginTransaction())
    {
        this.Session.Save(BookToAdd);
        tx.Commit();
    }

    return true;

}

我得到的错误是

GenericADOException was unhandled by user code
could not insert: [DA.Step][SQL: INSERT INTO Steps (BookId, Name) VALUES (?, ?); select SCOPE_IDENTITY()]

{"The INSERT statement conflicted with the FOREIGN KEY constraint \"FK_Steps_Book\". The conflict occurred in database \"Books\", table \"dbo.Book\", column 'Id'.\r\nThe statement has been terminated."}

2 个答案:

答案 0 :(得分:1)

步骤类的BookId未被设置,因此它将尝试插入null来打破FK。

定义关系的两面
在步骤映射中将步骤类的bookid定义为book并将其映射为多对一。

在书籍映射上将步骤一对多标记为inverse = true。仅在集合上标记为反向。

映射关系的两面让我们了解它需要插入的顺序。

答案 1 :(得分:0)

您需要添加inverse="true"

<set name="Steps" table="Steps" cascade="all" inverse="true">
  <key column="BookId"/>
  <one-to-many class="Step"/>
</set>