我(我的班级)有一个父子关系,我希望孩子只知道父母的id。
这样,如果我只需要一个孩子的详细信息,那么将加载完整的父母与对象图的其余部分。
因为我在db中激活了外键约束,所以在保存时会出现违规。要解决我需要这两步的方法:
class Child
{
public virtual Guid IdParent { get; set; }
}
class Parent
{
void AddChild(Child c)
{
c.IdParent = this.Id;
this.childs.Add(c);
}
}
var parent = new Parent()
session.Save(parent) // now the parent has an id
var child = new Child();
parent.Add(child); // child now knows the parent id
session.Save(child);
我真正想要的是
var parent = new Parent();
var child = new Child()
parent.AddChild(child);
session.Save(parent);
在nhibernate知道id之后,有没有办法在子节点上存储父ID?我还希望在db中激活外键检查。
父母的映射:
this.HasMany<Child>(x => x.childs)
.Not.LazyLoad()
.AsBag()
.Inverse()
.Cascade.AllDeleteOrphan()
.KeyColumn("id_parent");
答案 0 :(得分:1)
建议:我。我们需要的是更改您的C#实体。孩子应该(没有必要)将父母作为参考:
class Child
{
//public virtual Guid IdParent { get; set; }
public virtual Parent Parent { get; set; }
}
然后我们可以使用NHibernate的全部功能,即使在创建的情况下,只有在INSERT之后才知道父ID。 NHibernate将能够获取生成的ID(一旦生成)并将其正确存储在“id_parent”列中
如果你不想发布该属性,它可以被保护......并且IdParent可能只是公共的bug
class Child
{
public virtual Guid IdParent { get; set; }
protected virtual Parent Parent { get; set; }
}
但是,我们仍然可以通过引用将Child正确地映射到父级。
II。如果您不会更改映射,并且您将在HasMany
(集合映射)上使用级联它仍然可以正常工作......但没有 Inverse()
如果孩子确实知道父母......而不是父母,那么逆可能只有效。为什么?因为在创建Parent的情况下,在分配给子(您的AddChild方法)时的父ID不一定是正确的
总结:C#就是我们手中所拥有的(有时我们面对的是传统数据库)。我强烈建议:以最“标准”的方式改变你的模型。双向映射和关系是正确的方法,稍后将为您提供强大的功能,如过滤/搜索
III。级联摘要:
NHibernate支持此功能,称为cascading
。它完全符合您的需求。见:
<bag
...
cascade="all|none|save-update|delete|all-delete-orphan" (6)
(6)
cascade
(可选 - 默认为无)启用级联到子实体的操作
说,有这样的映射:
映射子集合的片段:
<bag name="Children" inverse="true" cascade="all">
<key column="parent_id"/>
<one-to-many class="Child"/>
</bag>
并形成那一刻你所需的语法将同时保存父母和孩子