【问题标题】:Fluent NHibernate HasMany mapping inserts null in foreign keyFluent NHibernate HasMany 映射在外键中插入 null
【发布时间】:2013-04-24 05:00:54
【问题描述】:

我有 2 个实体:

public class Parent
{
    public virtual string Number { get; set; }
    public virtual IList<Child> Children { get; set; }
    public Parent()
    {
        Phones = new List<Child>();
    }
}
public class Child
{
    public virtual string Number { get; set; }
    public virtual Parent Parent { get; set; }
}

和映射:

 public ChildMap()
        {
            Map(x => x.Number).Not.Nullable();
            References(x => x.Parent).Nullable().LazyLoad().Cascade.None();
        }

父母

public ParentMap()
    {
        Map(x => x.Number).Not.Nullable();
        HasMany(x => x.Children).Inverse().Cascade.All();
    }

但是当我向父级插入子级时,它在父级外键中带有 null。

var p = rep.Get(g => g.Id == 1);
Enumerable.Range(0, 100).Select(s => new Child()
    {
        Number = s.ToString()
    }).ToList().ForEach(p.Children.Add);
rep.Update(p);
rep.Flush();

实际上一切都像帖子NHibernate fluent HasMany mapping inserts NULL Foreign key
但是插入这样的链接test.Orders.Add(new Order("test") { Company = test });绝对不是真的方式,所以我需要帮助,有什么想法吗?

【问题讨论】:

    标签: c# fluent-nhibernate foreign-keys mapping fluent-nhibernate-mapping


    【解决方案1】:

    您在ParentChild 之间设置了双向关系,但是当您将子代添加到ParentChildren 集合时,您并没有为每个子代设置Parent 属性。

    我建议的第一件事是质疑这种关系是否需要是双向的 - 典型用法是否适用于独立于父母的孩子?您是否需要在从ChildParent 的方向上导航对象图? ParentChild 都是 Aggregate Roots 吗?

    有几种不同的方法可以处理双向关系。一种方法是定义 Add 和 Remove 方法,将 Child 添加到 Children 集合并在每个子项上设置 Parent 属性,并删除将子项直接添加到集合的能力,方法是将其设置为 @ 987654334@(或IReadOnlyCollection&lt;Child&gt;,或类似名称)例如带有IList&lt;Child&gt; 支持字段

    public class Parent
    {
        private IList<Child> _children;
    
        public Parent()
        {
            _children = new List<Child>();
        }
    
        public virtual string Number { get; set; }
        public virtual IEnumerable<Child> Children { get { return _children; } }
    
        public virtual void AddChild(Child child)
        {
            _children.Add(child);
            child.Parent = this;
        }
    
        public virtual void RemoveChild(Child child)
        {
            _children.Remove(child);
            child.Parent = null;
        }
    }
    
    public class Child
    {
        public virtual string Number { get; set; }
        public virtual Parent Parent { get; set; }
    }
    

    应修改 ParentMap 以使用支持字段

    public ParentMap()
    {
        Map(x => x.Number).Not.Nullable();
        HasMany(x => x.Children).Inverse()
                                .Cascade.All()
                                .Access.CamelCaseField(Prefix.Underscore);
    }
    

    【讨论】:

    • 对 Child 类中的 Parent 做同样的事情似乎很好。
    • @mehdi.loa Parent 拥有关系,因此在添加到Parent上的子集合时设置属性是有意义的。
    • @Roar 什么不灵活?
    • @RussCam 我不想添加其他方法,我需要为每个孩子获取父项的映射
    • @Roar 这是与 NHibernate 建立双向关系的一般方法。如果关系不需要需要是双向的,请从Child 中删除Parent 属性并使用您已有的属性;将在Child 表上为您创建Parent 表的外键。
    【解决方案2】:

    改为:

    Enumerable.Range(0, 100).Select(s => new Child()
        {
            Number = s.ToString(),
            Parent = p
        }).ToList().ForEach(p.Children.Add);
    

    【讨论】:

    • 但是插入这样的链接 test.Orders.Add(new Order("test") { Company = test });绝对不是真的方法,所以我需要帮助,有什么想法吗?
    • 这有什么问题?
    • 意外地,有人可以添加子属性 parent 未链接到 p
    • 您可以使用 ObservableCollection 而不是使用 List,并在 CollectionChanged 事件处理程序中设置父级。
    【解决方案3】:

    答案是

    public ParentMap()
        {
            Map(x => x.Number).Not.Nullable();
            HasMany(x => x.Children).Cascade.All();
        }
    

    没有逆向

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-03
      • 2012-10-19
      • 1970-01-01
      • 2013-09-01
      • 1970-01-01
      • 2014-05-26
      • 1970-01-01
      • 2011-04-15
      相关资源
      最近更新 更多