Nhibernate 向行李收集添加/删除物品
我正在与nHibernate合作,并试图了解袋子收集的意义。我的数据结构相对简单 条目:Nhibernate 向行李收集添加/删除物品,nhibernate,nhibernate-mapping,Nhibernate,Nhibernate Mapping,我正在与nHibernate合作,并试图了解袋子收集的意义。我的数据结构相对简单 条目: <class name="Entry"> <id name="id" column="EntryId"> <generator type="guid.comb"/> </id> <property name="Name" column="Name"/> <bag name="Results" table="Results" c
<class name="Entry">
<id name="id" column="EntryId">
<generator type="guid.comb"/>
</id>
<property name="Name" column="Name"/>
<bag name="Results" table="Results" cascade="all">
<key column="EntryId" />
<one-to-many class="Result"/>
</bag>
</class>
它似乎在数据库中创建条目记录,但不是结果记录。在我的数据库中,我在结果表中将EntryId作为外键。类似地,我希望能够从集合中删除result对象,并将其持久化到数据库中。我以为级联功能解决了这个问题,但不确定我做错了什么
编辑
我现在可以将结果对象添加到数据库中,但删除似乎不起作用:
Entry entry = Entry.Load(id);
entry.Results.Remove(result);
dbSession.SaveOrUpdate(entry);
我尝试添加cascade=“all delete orphan”,但这似乎同时删除了父项和子项。我只希望它从数据库中删除一个条目对象???要添加到集合中,您需要在添加子对象时显式保存它。从集合中删除对象时也是如此 所以你会这样做:
entry.Results.Add(result);
session.Save(result);
session.Save(entry);
session.Flush();
外键也必须为空。您必须这样做的原因是NHibernate必须首先保存子对象,而不与父对象关联。然后,当保存父项时,子项上的外键列将使用父项的Id进行更新,从而创建关系。这是因为在第二个操作(保存父项)完成之前,NHibernate可能没有所需的父项id键值
我想你已经弄明白这部分了
Delete的工作方式相同,原因不同-从父集合中删除子集合,然后显式删除子集合,然后更新父集合:
entry.Results.Remove(result);
session.Delete(result);
session.Update(entry);
session.Flush();
您从集合中删除了结果并更新了条目。这只会告诉Nhibernate删除条目和结果之间的关系-您从未实际删除结果对象本身。我注意到,在您的集合中,您将FK列定义为:
<key column="EntryId" />
但是您没有覆盖多对一
中的列
,这意味着您对同一关系有两个不同的列(Entry和EntryId)
也许是这样,也许不是。。。但检查一下也无妨:-)最后,这归结于我的hbm文件映射不正确 Entry.hbm.xml
<bag name="Results" table="Result" lazy="false" inverse="true" cascade="all-delete-orphan">
<key column="EntryId"/>
<one-to-many class="Result"/>
</bag>
删除:
entry.Results.Remove(result);
session.SaveOrUpdate(entry);
如果您使用的是代码映射,那么请同时使用Cascade.All和Cascade.delete孤儿选项。与xml映射不同,在按代码映射中没有“全部删除孤立项”的单一选项
Bag(x => x.Results, c =>
{
c.Key(k =>
{
k.Column("EntryId");
});
c.Cascade(Cascade.All | Cascade.DeleteOrphans);
}, r => r.OneToMany())
我也这么认为,但事实并非如此。我的答案已经提供。
<many-to-one name="Entry" class="Entry" column="EntryId"/>
Result r = new Result();
Entry entry = new Entry();
// AddResult method sets the Entry object of the Result
// result.Entry = this;
entry.AddResult(r);
session.SaveOrUpdate(entry);
entry.Results.Remove(result);
session.SaveOrUpdate(entry);
Bag(x => x.Results, c =>
{
c.Key(k =>
{
k.Column("EntryId");
});
c.Cascade(Cascade.All | Cascade.DeleteOrphans);
}, r => r.OneToMany())