NHibernate父子关系和子只知道parentId(foreignKey违规)

时间:2014-07-16 06:14:42

标签: c# nhibernate foreign-keys

我(我的班级)有一个父子关系,我希望孩子只知道父母的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");

1 个答案:

答案 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。它完全符合您的需求。见:

6.2. Mapping a Collection

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

并形成那一刻你所需的语法将同时保存父母和孩子