我有一个书对象,有步骤。这些反映在下面的映射文件和类中
<?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 :(得分: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>