2014-04-08 53 views
0

我有一本書對象,它有一些步驟。這些都反映在映射文件和類下面Nhibernate保存失敗 - 一對多

<?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."} 

回答

0

您需要添加inverse="true"

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

步驟類的BookId沒有被設置,因此它會嘗試插入null來打破FK。

定義關係
在步映射的兩側上的步驟類作爲書限定BOOKID並將其映射爲多對一。

在書映射標記步驟一對多爲inverse = true。只在集合上標記爲反向。

映射關係的兩側讓我們nhibernate瞭解它需要插入的順序。