1

我有两个实体:

public class Parent()
{
    public ICollection<Child> Children { get; set; }
}

public class Child()
{
    public Parent Parent { get; set; }
}

映射如下所示:

public class ParentMap : ClassMap<Parent>
{
    HasMany(x => x.Children).Cascade.All().Inverse();
}

public class ChildMap : ClassMap<Child>
{
    References(x => x.Parent).Cascade.None();
}

通常,为了拯救父母或孩子,您必须执行以下操作:

var parent = new Parent();
var child = new Child();

parent.Children.Add(child);
child.Parent = parent;

Session.SaveOrUpdate(parent);

换句话说,您必须在这两个对象中设置属性,以便 NHibernate 正确地保留此实体。

但是,对于遗留问题,我想保存这个实体而不必设置双方,这样我就可以这样做:

var parent = new Parent();
var child = new Child();
child.Parent = parent;

Session.SaveOrUpdate(child);

在这种情况下,我不将子对象添加到父Children集合中,我只是Parent在子对象上设置。

有什么方法可以让 NHibernate 正确地保存它,这样当我从数据库中取出父级时,它的Children集合中就会有子级?

PS 我意识到会话缓存存在潜在问题,并且依赖 NHibernate 执行一些幕后操作以使数据模型正确,但我现在忽略了这个问题。

4

1 回答 1

2

将 Parent 映射为 Child 中的私有字段:

public class ChildMap : ClassMap<Child>
{
    References(x => x.Parent).Cascade.None()
        .Access.CamelCaseField(Prefix.Underscore);
}

并通过公共财产控制它:

public class Child()
{
    private Parent _parent;

    public Parent Parent
    {
        get { return _parent; }
        set
        {
            _parent = value;
            _parent.Children.Add(this);
        }
    }
}

但是您现在拥有的代码应该可以按预期工作。您不必将 Child 添加到 Parent's Children 集合以使 NH 持久保存它,因为它被标记为关系的反面。添加它以使内存中的对象与数据库保持同步。如果您在子级上设置父级,刷新会话并在新会话中重新加载父级,则子级集合应该包含子级(假设二级缓存不发挥作用)。

编辑:要将子级添加到父级,请将操作封装在一个方法中:

public void AddChild(Child child)
{
    _children.Add(child);
    child.Parent = this;
}
于 2010-03-10T22:30:02.090 回答