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

发布于 2024-08-24 11:48:38 字数 1092 浏览 9 评论 0原文

我有两个实体:

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集合中,我只是在子对象上设置了父对象。

有什么方法可以让 NHibernate 正确地持久化这一点,以便当我从数据库中获取父级时,它会将子级包含在其 Children 集合中?

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

I have two entities:

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

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

The mapping looks like so:

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

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

Normally, in order to save a parent or a child, you'd have to do something like this:

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

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

Session.SaveOrUpdate(parent);

In other words, you have to set the properties in both objects in order for NHibernate to persist this entity correctly.

However, for legacy issues, I'd like to save this entity without having to set both sides, so that I can just do:

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

Session.SaveOrUpdate(child);

In this case, I don't add the child to the parent's Children collection, I just set the Parent on the child object.

Is there any way to get NHibernate to persist this correctly so that when I grab the parent out of the database, it will have the child inside its Children collection?

P.S. I realize that there's a potential issue here with the session cache and relying on NHibernate to perform some behind-the-scenes operations to make the data model correct, but I'm ignoring this issue for now.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

安人多梦 2024-08-31 11:48:38

将 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 持久化它,因为它被标记为关系的反面。您添加它是为了使内存中的对象与数据库保持同步。如果您在子级上设置父级,刷新会话,然后在新会话中重新加载父级,则子级集合应包含子级(假设二级缓存不发挥作用)。

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

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

Map Parent as a private field in Child:

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

and control it through the public property:

public class Child()
{
    private Parent _parent;

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

But the code you have now should work as expected. You don't have to add the Child to the Parent's Children collection to get NH to persist it because it's marked as the inverse side of the relationship. You add it to keep the in-memory objects in sync with the database. If you set the Parent on the Child, flush the session, and re-load the parent in a new session then the Children collection should contain the child (assuming 2nd level cache doesn't come into play).

Edit: To add the child to the parent, encapsulate the action in a method:

public void AddChild(Child child)
{
    _children.Add(child);
    child.Parent = this;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文