Search code examples
c#fluent-nhibernatefluent-nhibernate-mapping

Problem mapping reference to composite key with Fluent NHibernate


  • I have a class named... "ClassA" that has an int ID as primary key.
  • I have a class named "ClassB" that has a composite primary key formed by an Id, a ClassAId that is a reference to ClassA, and another int named Version.
  • And I have a class named C that has an int ID as primary key, and a foreign key to ClassB composed of ClassBId, ClassAId, and Version.

I don't find a way to map that with Fluent NHibernate.

My class definitions are like this -I'll omit the Equals and GetHash part-:

public class ClassA
{
    public virtual int Id { get; set; }
}
public class ClassB
{
    public virtual int Id { get; set; }
    public virtual ClassA ClassA { get; set; }
    public virtual ICollection<ClassC> ClassCCollection { get; set; }
}
public class ClassC
{
    public virtual int Id { get; set; }
    public virtual ClassB ClassB { get; set; }
}

And my mapping constructors:

public ClassAMap()
{
    Table("ClassA");
    Id(c => c.Id);
}
public ClassBMap()
{
    Table("ClassB");
    CompositeId()
        .KeyProperty(c => c.Id)
        .KeyReference(c => c.ClassA, "ClassAId")
        .KeyProperty(c => c.Version);
    HasMany(c => c.Edges)
        .Inverse()
        .Cascade.All().AsList().KeyColumns.Add("ClassBId", "ClassAId", "Version");
}
public ClassCMap()
{
    Table("ClassC");
    Id(c => c.Id);
    References(n => n.ClassB).Columns("ClassBId, ClassAId, Version").Not.Nullable();
}

But when I try to launch the application, the SchemaUpdate says that

FKUnmatchingColumnsException: Foreign key (FK_6C7456E0:ClassC [ClassBId, ClassAId, Version])) must have same number of columns as the referenced primary key (ClassB [Id, ClassAId, Version])

Maybe I'm not so good at math, but it seems that 3 columns have the same number of columns than 3. Am I missing something? Thanks.


Solution

  • Very stupid mistake:

    I was writing

    References(n => n.ClassB).Columns("ClassBId, ClassAId, Version").Not.Nullable();
    

    Putting the three columns in the same string. When it should be:

    References(n => n.ClassB).Columns("ClassBId", "ClassAId", "Version").Not.Nullable();
    

    A lapsus that had me stuck for two days.