1

Just to be clear - this question is not about Fluent NHibernate.

I have a Parent and Child classes, with a one-to-many relationship between them.

The code is shortened for readability.

public class Child
{
    int Id;
    string Name;
}

public class Parent
{
    int Id;
    string Name;
    Iesi.Collections.Generic.ISet<Child> Children;
}

public ChildMapping()
{
    Table("Children");

    Id(p => p.Id, m => {
        m.Column("Id");
        m.Generator(Generators.Identity);
    });

    Property(p => p.Name, m => {
        m.Column("Name");
        m.NotNullable(true);
    });
}

public ParentMapping()
{
    Table("Parents");

    Id(p => p.Id, m => {
        m.Column("Id");
        m.Generator(Generators.Identity);
    });

    Property(p => p.Name, m => {
        m.Column("Name");
        m.NotNullable(true);
    });

    Set(p => p.Children, m => {
        m.Cascade(Cascade.All | Cascade.DeleteOrphans);
        m.Key(k => {
            k.Column("ParentId");
            k.NotNullable(true);
        });
    }, a => a.OneToMany());
}

The Child class needs a Parent property on it. The Parent needs to control the relationship (I can't set the Inverse to true on the Parent's end).

How should the Parent and Child mapping look like?

Marcin Seredynski
  • 7,057
  • 3
  • 22
  • 29
  • 2
    you may find this series of blog posts useful; it's practically the only documentation I could find of mapping-by-code. http://notherdev.blogspot.co.il/2012/02/nhibernates-mapping-by-code-summary.html – J. Ed Aug 23 '12 at 18:05
  • Thank you. It's also the only documentation I've found, but it didn't help me much. If I manage to figure this out, I'll answer the question myself :) – Marcin Seredynski Aug 24 '12 at 09:27
  • well, the parent mapping seems ok, don't you just need a `many-to-one` on the child end and that's it? – J. Ed Aug 24 '12 at 19:22

1 Answers1

2

I've added the following items:

Child class: a field _parent, a constructor
Parent class: AddChild method
Child mapping: manytoone for parent property
Parent mapping: inverse(true) to make parent handler of the children

Complete code:

public class Child
{
    int Id;
    string Name;
    Parent _parent;

    public Child(Parent parent)
   {
     _parent = parent;
   }
}

public class Parent
{
    int Id;
    string Name;
    Iesi.Collections.Generic.ISet<Child> Children;

    public virtual Child AddChild()
    {
       Child newChild = new Child(this); //link parent to child via constructor
       Children.Add(newChild); //add child to parent's collection
       return newChild; //return child for direct usage
    }
}

public ChildMapping()
{
    Table("Children");

    Id(p => p.Id, m => {
        m.Column("Id");
        m.Generator(Generators.Identity);
    });

    Property(p => p.Name, m => {
        m.Column("Name");
        m.NotNullable(true);
    });

    ManyToOne(x => x.Parent, map => {
         map.Column("Id"); /* id of the parent table */
         map.Access(Accessor.Field);
         map.NotNullable(true);
         map.Class(typeof(Parent));
        });    
}

public ParentMapping()
{
    Table("Parents");

    Id(p => p.Id, m => {
        m.Column("Id");
        m.Generator(Generators.Identity);
    });

    Property(p => p.Name, m => {
        m.Column("Name");
        m.NotNullable(true);
    });

    Set(p => p.Children, m => {
        m.Cascade(Cascade.All | Cascade.DeleteOrphans);
        m.Key(k => {
            k.Column("Id"); /* id of the child table */
            k.NotNullable(true);
            k.Inverse(true); /* makes the parent handle it's childlist */
        });
    }, a => a.OneToMany());
}

that should work.

TedOnTheNet
  • 1,082
  • 1
  • 8
  • 23