双向保存的流畅nhibernate映射
本文关键字:nhibernate 映射 保存 | 更新日期: 2023-09-27 18:01:51
我希望能够做到以下几点:
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()
时保存所有创建的对象。这是课程。我不知道如何在Parent
和Child
之间做一对多关系的映射,这将有助于在一次调用Save()
中保存所有创建的对象。我希望任何一个版本都可以使用,但在任何给定的时间只会使用一个。这背后的基本原理是,我正在创建测试数据构建器,在某些情况下,从Child
端连接起来会更容易,在其他情况下,从Parent
端连接起来会更容易。因此,为什么我希望能够级联插入和删除在两个方向给定的对象。我不关心更新。这将只用于插入数据,对应用程序运行我的测试,然后删除数据。
下面是所涉及的类:
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);
}
}
为了能够从两边保存级联,我们可以使用级联设置
那么,这个映射就足够了:
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)。父参考)
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);
在这里阅读更多关于批大小的信息(不是问题的一部分,但我总是使用它)
关于逆映射和引用赋值的其他一些细节
为什么我们不能在。references()(多对一)NHibernate多对一级联上使用相同的级联