views:

253

answers:

1

Hi everyone. My problem is fluent nhibernate mapping a many to many relationship, they end up referencing a non existent Id.

public UserMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);
        Map(x => x.Password);
        Map(x => x.Confirmed);
        HasMany(x => x.Nodes).Cascade.SaveUpdate();
        HasManyToMany<Node>(x => x.Events).Cascade.SaveUpdate().Table("RSVPs");
    }

public EventMap()
    {

        Map(x => x.Starts);
        Map(x => x.Ends);
        HasManyToMany<User>(x => x.Rsvps).Cascade.SaveUpdate().Table("RSVPs");
    }

public NodeMap() {
        Id(x => x.Id);

        Map(x => x.Title);
        Map(x => x.Body).CustomSqlType("text");
        Map(x => x.CreationDate);
        References(x => x.Author).Cascade.SaveUpdate();
        Map(x => x.Permalink).Unique().Not.Nullable();

    }

Those are my classes -notice that Event inherits from Node:

public class Event : Node//, IEvent
{
    private DateTime _starts = DateTime.MinValue;
    private DateTime _ends = DateTime.MaxValue;
    public virtual IList<User> Rsvps { get; set; }

}

The problem is, the generated RSVPs table is like that:

Event_id User_id Node_id

Of course the Event table has no ID - only a Node_id.

When trying to save a relationship it will try to save a NULL event_id thus generating an error.

A: 

Ok, I should have known fluent NHibernate better: after some trial and error, everything works. However, I should deepen my knowledge. This is the working code:

public class UserMap : ClassMap<User>
{
    public UserMap()
    {
        Id(x => x.Id);
        Map(x => x.Name);
        Map(x => x.Password);
        Map(x => x.Confirmed);
        HasMany(x => x.Nodes).Cascade.SaveUpdate();
        HasManyToMany<Node>(x => x.Events)
            .Table("RSVPs")
            .ParentKeyColumn("User_id")
            .ChildKeyColumn("Event_id");
    }
}

public EventMap()
    {

        Map(x => x.Starts);
        Map(x => x.Ends);
        HasManyToMany(x => x.Rsvps)
            .Cascade.SaveUpdate()
            .Table("RSVPs")
            .Inverse()
            .ParentKeyColumn("Event_id")
            .ChildKeyColumn("User_id");
    }

public NodeMap() 
{
        Id(x => x.Id);

        Map(x => x.Title);
        Map(x => x.Body).CustomSqlType("text");
        Map(x => x.CreationDate);
        References(x => x.Author).Cascade.SaveUpdate();
        Map(x => x.Permalink).Unique().Not.Nullable();
    }

(The node and event class remain the same)

I had to specify:

  1. The name of the table
  2. The name of ParentKeyColumn and ChildKEyColumn (notice they are the inverse in the two classes)
  3. Inverse on the mapping of EventMap

Hope this can help someone as a HasManyToMany / SubclassMap example.

Davide Orazio

Davide Orazio Montersino

related questions