如何在Fluent NHibernate中保存具有双向关系的实体而不设置双方?

时间:2010-03-10 21:46:15

标签: nhibernate fluent-nhibernate nhibernate-mapping bidirectional

我有两个实体:

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集合中?

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

1 个答案:

答案 0 :(得分: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的Children集合中以使NH保持它,因为它被标记为关系的反面。您添加它以保持内存中的对象与数据库同步。如果在子项上设置Parent,则刷新会话,并在新会话中重新加载父项,然后Children集合应包含子项(假设二级缓存不起作用)。

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

public void AddChild(Child child)
{
    _children.Add(child);
    child.Parent = this;
}