【问题标题】:NHibernate: bidirectional many-to-one problemNHibernate:双向多对一问题
【发布时间】:2010-04-01 21:42:07
【问题描述】:

我在 NHibernate 中有一个双向关系:

<class name="Child" table="Children">
  <many-to-one name="Parent" column="ParentId" not-null="true" />
</class>

<class name="Parent">
  <set name="Children" lazy="true" table="Children" cascade="all">
    <key column="ParentId" not-null="true" />
    <one-to-many class="Child" />
  </set>
</class>

如何在不设置 inverse="true" 并在 Child 上设置 Parent 属性的情况下保存它?
我不想这样做,因为从 POCO 的角度来看它没有多大意义。

或者,是否可以拦截在 NHibernate 代理集合 (Children) 上调用的 Add?
在那种情况下,我会把 Parent 设置逻辑放在这里。

【问题讨论】:

    标签: nhibernate poco many-to-one


    【解决方案1】:

    除非您愿意让外键为空并接受插入后更新,否则这就是 NHibernate 中双向一对多的工作方式。

    我确实有这个模式的通用实现,你可以使用......这是一个概念证明;它可能有用与否,取决于你如何看待它,因为它有点打破 POCO 方法,但是......好吧,它是:

    public interface IHaveParent<T>
    {
        T Parent { get; set; }
    }
    
    public interface IHaveMany<T>
    {
        ICollection<T> Children { get; }
    }
    
    public static class OneToManyHelper
    {
        public static void AddChild<TParent, TChild>(this TParent parent,
                                                     TChild child)
        where TChild : IHaveParent<TParent>
        where TParent : IHaveMany<TChild>
        {
            parent.Children.Add(child);
            child.Parent = parent;
        }
    }
    

    有了这个,你可以在任何父母上都AddChild

    拦截 Add 调用的问题在于,您总是需要使用特殊方法(同样不是 POCO)来实例化您的集合。

    【讨论】:

    • 好吧,如果我可以创建一个在 Add/Insert 上设置它的自定义集合,这将是 POCO,因为它在大多数 UI 框架中以这种方式工作,只是为了 Parent 值的一致性(根本不考虑保存)。然后我可以在构造函数中设置它。但我可以吗? NH 会将其包装在代理中还是将其替换为代理
    • NHibernate 总是替换你的收藏。你可以定义使用什么类型,看unhaddins.googlecode.com/svn/trunk/uNhAddIns/uNhAddIns.WPF。但是,在我看来,处理您的父/子关系比仅设置父级、向您的父级添加通常的 AddChild 方法或使用如上所示的显式双向关系要复杂得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 2011-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多