Fluent nHibernate - Mapping Children with Composite Keys Yielding Null References

本秂侑毒 提交于 2019-12-22 10:16:11

问题


Given a simple parent -> child (CK,CK) setup like this .. I am having trouble with adding a new child object and it getting the parent reference. So I would add the object in such a way ..

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

Or even adding it using the Add() method...

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

The reference to the Parent does not get pushed through. It just ends up as a null property. I get the following exception.

{"Cannot insert the value NULL into column 'ParentId', table 'mssql_test.Children'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}

I can do this ...

new Child { 
   Parent = parentReference,
   Other = otherReference
}

But that seems a bit redundant. My understanding is that it should be able to infer the reference by itself. If this is not possible, perhaps I am just misunderstanding. Can anyone help me? I have an outline of my code below.

Classes

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
}

Mapping

 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]");
}

回答1:


As @KeithS points out the problem is that you have mapped the Child collection as HasManyToMany when it should be HasMany. Here is how the mapping should look:

  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]");
  }



回答2:


You are not mapping the Parent as a property of the Child. NHibernate (and FluentNH) only map what you tell them to; you could have a dozen fields on your object, but if you only map one of them, that's all NH will provide when it hydrates an instance for you. You should include a "References" method to the Parent in your mapping, specifying the Parent's key field as the FK reference. That should give you the "backreference" you have in your object hierarchy.

Also, it looks like instead of a many-to-many on the Parent side, you should have just a one-to-many (using HasMany). Parents can have many Children, but a Child has one and only one Parent. ManyToMany may work, but it creates a redundant cross-reference table in between Parent and Child.



来源:https://stackoverflow.com/questions/5900383/fluent-nhibernate-mapping-children-with-composite-keys-yielding-null-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!