简体   繁体   English

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

[英]fluent nhibernate mappings that save in both directions

I want to be able to do the following: 我希望能够做到以下几点:

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

session.Save(child);

OR 要么

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

session.Save(parent);

and have it in both cases save all of the created objects when Save() is called. 并且在两种情况下都可以在调用Save()Save()所有创建的对象。 Here are the classes. 这是课程。 I do not know how to do the mapping of the one to many relationship between Parent and Child that will facilitate saving all of the created objects in one call to Save() . 我不知道如何映射ParentChild之间的一对多关系,这将有助于在一次调用Save()保存所有创建的对象。 I expect that either version can be used, but only one will be used at any given time. 我希望可以使用任何一个版本,但在任何给定时间只能使用一个版本。 The rationale behind this is that I'm creating test data builders and in some cases it will be easier to wire it up from the Child side and in other cases it will be easier to wire up from the Parent side. 这背后的基本原理是我正在创建测试数据构建器,在某些情况下,从Child端更容易连接它,在其他情况下,从Parent端更容易连接。 Hence why I want to be able to cascade inserts and deletes in both directions given either object. 因此,为什么我希望能够在给定任一对象的情况下在两个方向上级联插入和删除。 I don't care about updates. 我不关心更新。 This will only be used to insert data, run my tests against the app, then delete the data. 这只会用于插入数据,对应用程序运行我的测试,然后删除数据。

Here are the classes involved: 以下是涉及的课程:

public class Child {
  public virtual int Id { get; set; }
  public virtual string Name { get; set; }
  public virtual Parent Parent { get; set; }
}

public class Parent {
  public virtual int Id { get; set; }
  public virtual string Name { get; set; }
  public virtual IEnumerable<Child> Children { get; set; }
}

public ChildMap : ClassMap<Child> {
  public ChildMap() {
    Id(x => x.Id);
    Map(x => x.Name);

    // How should I set this up?
    Reference(x => x.Parent);
  }
}

public ParentMap : ClassMap<Parent> {
  public ParentMap() {
    Id(x => x.Id);
    Map(x => x.Name);

    // How should I set this up ?
    HasMany(x => x.Children);
  }
}

To be able save cascades from both sides, we can just use cascade setting 为了能够从两侧保存级联,我们可以使用级联设置

So, this mapping would be enough: 所以,这种映射就足够了:

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()
       ;

With these settings, the above would work, with one important change - children MUST know about its parent. 有了这些设置,上面的方法就可以了,有一个重要的变化 - 孩子们必须知道它的父母。 Because we use inverse... 因为我们使用逆...

This will work: 这将有效:

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);

And this will as well (but with setting child.Parent reference) 这也将(但设置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);

Read more here about the batch size (not part of a question, but I do use it always) 在这里阅读更多有关批量大小的信息 (不是问题的一部分,但我总是使用它)

Some other details about inverse mapping and reference assignment 关于逆映射和引用赋值的一些其他细节

And also, why we cannot use the same cascade on .Rferences() (many-to-one) NHibernate Many-to-one cascade 而且,为什么我们不能在.Rferences()(多对一)上使用相同的级联NHibernate多对一级联

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM