流畅的nHibernate - 使用复合键映射孩子产生空引用

时间:2011-05-05 15:32:48

标签: c# fluent-nhibernate composite-key

给出一个简单的父母 - > child(CK,CK)设置如下..我在添加新的子对象时遇到问题,并且它获得了父引用。所以我会以这种方式添加对象..

var parent = new Parent{
  Children = new List<Child>{
   new Child{
     Other = otherReference
   }
  }
};

甚至使用Add()方法添加它......

  

parent.Children.Add(new Child {Other = other});

Parent的引用未被推送。它最终只是一个null属性。我得到以下异常。

  

{“无法将值NULL插入列'ParentId',表'mssql_test.Children';列不允许空值.INSERT失败。\ r \ n语句已终止。”}

可以这样做......

new Child { 
   Parent = parentReference,
   Other = otherReference
}

但这似乎有点多余。我的理解是它应该能够自己推断出引用。如果这是不可能的,也许我只是误解。谁能帮我?我在下面概述了我的代码。

class Parent {
  int Id { get; set; }
  IList<Child> Children { get; set; }
}
class Other {
  int Id { get; set; }
}
class Child {
  Parent Parent { get; set; }
  Other Other { get; set; }
  // other properties
}

映射

 ChildMap() {
      CompositeId()
        .KeyReference(x => x.Parent, "ParentId")
        .KeyReference(x => x.Other, "OtherId");
    }

    ParentMap(){
     HasManyToMany(x => x.Children)
                    .AsBag()
                    .ChildKeyColumns.Add(new[] { "ParentId", "OtherId" })
                    .Inverse()
                    .Cascade.All())
                    .Table("[Test]");
}

2 个答案:

答案 0 :(得分:3)

正如@KeithS指出的那样,问题是你将Child集合映射为HasManyToMany,它应该是HasMany。以下是映射的外观:

  ChildMap() {
      CompositeId() //This is is good
        .KeyReference(x => x.Parent, "ParentId")
        .KeyReference(x => x.Other, "OtherId");
  }

  ParentMap(){ //This is the fix
        HasMany(c => c.Children)
          .Inverse()
          .Cascade.All()
          .KeyColumn("ParentId") //Not needed if Parent Id prop maps to ParentId col
          .Table("[Test]");
  }

答案 1 :(得分:0)

您没有将Parent映射为Child的属性。 NHibernate(和FluentNH)只映射你告诉他们的内容;你可以在你的对象上有十几个字段,但是如果你只映射其中一个字段,这就是NH为你提供实例时所提供的所有字段。您应该在映射中为Parent添加“References”方法,将Parent的键字段指定为FK引用。这应该为您提供对象层次结构中的“反向引用”。

此外,在Parent方面看起来不是多对多,你应该只有一对多(使用HasMany)。父母可以有很多孩子,但是孩子只有一个孩子。 ManyToMany可以工作,但它在Parent和Child之间创建了一个冗余的交叉引用表。