流畅的nhibernate映射,可以双向保存

时间:2015-07-09 20:23:04

标签: c# nhibernate fluent-nhibernate nhibernate-mapping fluent-nhibernate-mapping

我希望能够做到以下几点:

var child = new Child {
  Name = "foo",
  Parent = new Parent { Name = "bar" }
};

session.Save(child);

var parent = new Parent {
  Name = "foo",
  Children = new List<Child> {
    new Child { Name = "bar" },
    new Child { Name = "baz" },
  },
};

session.Save(parent);

并且在两种情况下都可以在调用Save()时保存所有创建的对象。这是课程。我不知道如何映射ParentChild之间的一对多关系,这将有助于在一次调用Save()中保存所有创建的对象。我希望可以使用任何一个版本,但在任何给定时间只能使用一个版本。这背后的基本原理是我正在创建测试数据构建器,在某些情况下,从Child侧更容易连接它,在其他情况下,从{{1}更容易连接起来方。因此,为什么我希望能够在给定任一对象的情况下在两个方向上级联插入和删除。我不关心更新。这只会用于插入数据,对应用程序运行我的测试,然后删除数据。

以下是所涉及的课程:

Parent

1 个答案:

答案 0 :(得分:2)

为了能够从两侧保存级联,我们可以使用级联设置

所以,这种映射就足够了:

public ChildMap() 
{
    ...
    BatchSize(100);  // this is the way how to solve 1 + N (good practice, mine at least)

    // How should I set this up?
    References(x => x.Parent) // References, not Reference
        .Cascade.SaveUpdate()
        ;
}

public ParentMap() 
{
    ...
    BatchSize(100);  // this is the way how to solve 1 + N

    // How should I set this up ?
    HasMany(x => x.Children)
       .BatchSize(100)  // no 1 + N
       .Cascade.AllDeleteOrphan()
       .Inverse()
       ;

通过这些设置,上述方法可行,但有一个重要的变化 - 孩子们必须知道它的父母。因为我们使用逆...

这将有效:

var child = new Child
{
    Name = "foo",
    Parent = new Parent {Name = "bar"}
};

session.Save(child);
session.Flush();
session.Clear();

var persistedChild = session.Get<Child>(child.ID);

这也将(但设置child.Parent参考)

var parent = new Parent
{
    Name = "foo",
    Children = new List<Child>
    {
        new Child {Name = "bar"},
        new Child {Name = "baz"},
    },
};

foreach (var ch in parent.Children)
{
    ch.Parent = parent; // we MUST do this, there is .Inverse()
}

session.Save(parent);
session.Flush();
session.Clear();

var persistedParent = session.Get<Parent>(parent.ID);

关于more here阅读batch size(不是问题的一部分,但我总是使用它)

关于逆映射和reference assignment

的其他一些细节

而且,为什么我们不能在.Rferences()(多对一)NHibernate Many-to-one cascade

上使用相同的级联