Mattygabe
Mattygabe

Reputation: 1790

Fluent Nhibernate HasMany to One Table from Several Tables

I have an entity/class/table which is referenced from several other entities, and I use Fluent NHibernate to handle the ORM for me. In a few instances, it's a simple reference where I can store the foreign key ID as a column and handle the reference in that simple way, but in a few other instances I need to reference a list of these items, and it needs done for at least three classes I can think of. You can assume this setup will be copied to handle the other classes' relationships.

Here's how the common entity looks (the one that is owned by several other entities in HasManys):

public class Student {
    public virtual int Id {get; set;}
    public virtual string Name {get; set;}
}

And, here's what the ShopCourse entity looks like:

public class ShopCourse {
    public virtual int Id {get; set;}
    public virtual int Name {get; set;}
    public virtual IList<Student> Students {get; set;}
}

Imagine that a couple other classes I have, such as specific courses, can "own" several students. In order to maintain that relationship I must create a table in my database that tracks the foreign keys between the two (for each entity that references Student) - no entity needed for this intermediate table, and Fluent won't need to think of it unless I hand it the string name of the table itself:

Table: ShopCourseStudents

int - ShopCourseId
int - StudentId

Lastly, here are my mappings. You can assume that the entities themselves map out fine - things such as the naming scheme for the Id are resolved and working correctly. The issue lies when I attempt to initialize any entity that has a HasMany of Student:

//Inside a FluentlyConfigure().Mappings(m => m.AutoMappings.Add() call:
.Override<ShopCourse>(map => {
    map.HasMany(x => x.Students)
        .Table("ShopCourseStudents")
        .KeyColumns.Add("ShopCourseId")
        .KeyColumns.Add("StudentId")
        .Cascade.All();
    })

The issue is that when I attempt to load a list of ShopCourses I get the Fluent error:

Foreign key (ABC123AF9:Student [ShopCourseId, StudentId]) must have same number of columns as the referenced primary key (ShopCourses [Id])

I do not override Fluent's mapping of Student as it's straightforward. For the purpose of this example, Student doesn't need to know which ShopCourses it belongs to, or any of the other courses that may own that particular Student record.

This seems like I'm doing something basic, wrong - what is it, exactly? Much obliged in advance!

Upvotes: 0

Views: 1288

Answers (1)

Mattygabe
Mattygabe

Reputation: 1790

So, the issue was with the custom code that I re-use with my projects, apparently the piece written to handle the ManyToMany convention is mostly broken. What I was looking for here was a ManyToMany relationship, not HasMany. The issue I had was that my code was forcing a reference on the child object (in this example, Student) to the parent, which I do not need and only complicates things. Removing that, and my ManyToMany then works:

.Override<ShopCourse>(map => {
    map.HasManyToMany(x => x.Students)
        .Table("ShopCourseStudents")
        .ParentKeyColumn("ShopCourseId")
        .ChildKeyColumn("StudentId")
        .Cascade.All()

Upvotes: 1

Related Questions