我正在尝试使用NHibernate建立一个简单的一对多关系/层次结构。我希望自动删除孤儿,但我目前的尝试都会导致ObjectDeletedException。我想知道是否有人可以告诉我我做错了什么。
修改
我应该指定我正在加载一个根Foo,然后删除会话之外的一个孩子,导致一个或多个孩子成为孤儿。当我随后在第二个会话中调用SaveOrUpdate(root)时发生异常。如何纠正分离和修改对象与数据库中持久对象之间的子代表区别?
有问题的示例代码如下所示:
Foo foo = new Foo();
Foo child1 = new Foo();
Foo child2 = new Foo();
foo.Children.Add(child1);
child1.Children.Add(child2);
// session #1
session.SaveOrUpdate(foo);
// so far, so good
// outside of any session
foo.Children.Clear();
// session #2
PutFoo(foo); // results in ObjectDeletedException
持久化对象:
class Foo
{
private IList<Foo> children = new List<Foo> children;
public virtual int Id { get; private set; }
public IList<Foo> Children
{
get { return children; }
set { children = value; }
}
}
FluentNHibernate映射:
class FooMap : ClassMap<SyncDir>
{
public FooMap()
{
Id(x => x.Id);
base.HasMany(x => x.Children).Cascade.AllDeleteOrphan();
}
}
用于保存Foo类型对象的方法:
void PutFoo(Foo foo)
{
using (var session = factory.OpenSession())
using (var transaction = factory.BeginTransaction())
{
session.SaveOrUpdate(foo);
transaction.Commit();
}
}
答案 0 :(得分:1)
我一直在做的是建立一种双向关系。
所以,这意味着孩子们可以参考他们的父母。 从集合中删除子节点时,我还将对父节点的引用设置为NULL。
在映射中,您还必须指出关系的“反向”结束。 我也从不在课堂外“按原样”展示这个系列。
因此,我大多是这样做的:
public class Foo
{
private ISet<Bar> _bars = new HashSet<Bar>();
public ReadOnlyCollection<Bar> Bars { get return new List<Bar>(_bars).AsReadOnly(); }
public void AddBar( Bar b )
{
b.Parent = this;
_bars.Add (b);
}
public void RemoveBar( Bar b )
{
b.Foo = null;
_bars.Remove (b);
}
}
public class Bar
{
public Foo Parent { get; set; }
}
然后,在映射中,我在集合上设置了“反向”结束。 所以,这意味着在我的映射中(我仍然使用xml文件来指定映射),我在Foo类的Bars集合上设置了inverse = true属性。